[Proj] libproj4 thread safety
Glynn Clements
glynn at gclements.plus.com
Fri Apr 22 18:03:52 EDT 2005
Gerald Evenden wrote:
> Returning to an old subject.
>
> As noted before, pj_strerrno appears to be the only current problem
> restricting libproj4 from working in a threads environment.
>
> This appears solvable by using a variant of the errno.h method.
>
> At the moment, I cannot see anyway to implement an errno method
> with the same transparency that the U**X library provides. It would
> appear that the user would have to do some extra extra code/calls to
> initialize pj_errno for threads operation and not simply use the
> libproj4 library as is---like one uses the libc library.
>
> It appears to me that setting up special calls related to TSD is
> required
> that cannot be hidden in a system that works in both the thread
> and linear mode.
>
> Is my assessment correct.?
>
> Comments please.
AFAICT, the required initialisation consists of calling
pthread_key_create() once then pthread_setspecific() once per thread,
before you read/write pj_errno.
You should be able to do both of these on first use. However, you need
to protect the key creation against race conditions using
pthread_once(), e.g.
static pthread_once_t proj_errno_key_once = PTHREAD_ONCE_INIT;
static pthread_key_t proj_errno_key;
static void proj_errno_key_create(void)
{
pthread_key_create(&proj_errno_key, proj_errno_destroy);
}
static void proj_errno_destroy(void *buf)
{
free(buf);
}
static int *proj_errno_location(void)
{
void *p;
pthread_once(&proj_errno_key_once, proj_errno_key_create);
p = pthread_getspecific(proj_errno_key);
if (!p) {
p = malloc(sizeof(int));
pthread_setspecific(proj_errno_key, p);
}
return (int *) p;
}
int *proj_errno_location(void)
{
return (int *) pthread_getspecific(proj_errno_key);
}
#define pj_errno (*(*proj_errno_location()))
--
Glynn Clements <glynn at gclements.plus.com>
More information about the Proj
mailing list