Soeren Gebbert wrote: > After reading some documentation and asking "silly" questions to > my poor informatics colleagues, i understand the concept of thread local and > the setjmp()/longjmp() approach a bit better. > > I would suggest to add longjmp() to G_fatal_error(). > It should be set at runtime by an application if longjmp() should be > chosen or not. > So G_fatal_error() will either call longjmp() or exit().
There's no need to modify G_fatal_error(). The application can install an error handler with G_set_error_routine(), and the error handler can use longjmp() to avoid returning. > The linux threaded errno definition scared me, so i have chosen a > different approach. > We define thread local support and two extern variables in gis.h to > choose at runtime if > G_fatal_error() will call exit() or longjmp() and to add thread local support. > > Example which works for me in my test code: > > /*Thread local and setjmp() exception support*/ > #include <setjmp.h> > #ifdef WIN32 > #define Thread __declspec( thread ) > #else > #define Thread __thread > #endif The __thread qualifier is a gcc extension. > extern Thread jmp_buf G_stack_buffer; /*to save the most important > CPU register for each thread*/ In order to use a GRASS library from multiple threads, the entire library state needs to be thread-specific. That would include the current error handler. Also: do you actually need to resume a thread in which an error occurs? If not, you can just make the error handler terminate the current thread. That will prevent the error handler from returning and thus prevent exit() being called. > Is this approach ok or to simple or just naive? :) It's too invasive. The longjmp() should go into an application-defined error handler, rather than the GRASS libraries. The only changes to the GRASS libraries regarding error handling should be to ensure that it is safe to continue using them after the application recovers from a fatal error. Supporting thread-local state requires some changes to the GRASS libraries, i.e. moving most[1] static variables for a library into a state structure, and referencing all such variables through a pointer. [1] Some variables will contain immutable data, e.g. tables which are read from files. These don't need to be initialised for each thread, although concurrent initialisation has to be protected against. > If this is ok, i would like to test this approach to identify possible > nested setjmp()/longjmp() > calls in libgis, libraster and libvector. I'd prefer to avoid putting any setjmp()s into the GRASS libraries. I'd rather see low-level functions split into an "internal" version which returns an error status, and a "public" version which calls G_fatal_error(), and have intermediate functions use the internal version if they need to catch errors. Ultimately, the GRASS libraries exist for the benefit of GRASS modules. Minor changes to facilitate other uses (e.g. persistent applications) are reasonable, but I'm opposed to substantial architectural changes, particularly if it makes the coding process more complex. -- Glynn Clements <[email protected]> _______________________________________________ grass-dev mailing list [email protected] http://lists.osgeo.org/mailman/listinfo/grass-dev
