[GRASS-dev] Using GRASS in long running and multithreaded applications Was: Re: The tomcat shut down ...

Soeren Gebbert soerengebbert at googlemail.com
Thu Oct 1 18:21:07 EDT 2009


Hello,

>> 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.

Yes, wikipedia says it works for:
Sun Studio C/C++, IBM XL C/C++, GNU C and Intel C/C++ (Linux systems)

Using the pthreads implementation will be a better solution?

>
>> 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.

I am not sure about this. If the grass libs are called from within an
EJB container, then there will be no way to terminate the current
thread. But it should work from within a servlet container or a RCP
container.

>
>> 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.

Ok. The error handler looks like that for now:

int vgb_error_handler(const char *msg, int fatal)
{
    if (fatal == 0)
    {
        fprintf(stderr, "%s\n", msg);
        return 1;
    }
    else if (fatal == 1)
    {
        fprintf(stderr, "WARNING: %s\n", msg);
        longjmp(vgb_stack_buffer, 1);
    }
    else if (fatal == 2)
    {
        fprintf(stderr, "ERROR: %s\n", msg);
        longjmp(vgb_stack_buffer, 2);
    }
    return 1;
}

vtkGRASSInit::vtkGRASSInit()
{
    G_gisinit("vtkGRASSInit");
    // Set the error routine
    G_set_error_routine(vgb_error_handler);
}

>
> 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.
> 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.

Ok, i agree. I will implement the setjmp()/longjmp() only within my application.

>
> 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.

Very much agreed.

Thanks
Soeren

>
> --
> Glynn Clements <glynn at gclements.plus.com>
>


More information about the grass-dev mailing list