[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