/* pqthreads.h -- libpq threads stuff */

#ifndef __pqthreads_h_
#define __pqhtreads_h_

#ifdef _THREADS_IMPLEMENTATION
#undef _THREADS_IMPLEMENTATION
#endif /* _THREADS_IMPLEMENTATION */

#ifdef MIT_PTHREADS

#ifdef _THREADS_IMPLEMENTATION
bogus -- more than one threads implementation selected. Make up your mind!
#endif /* _THREADS_IMPLEMENTATION */

#include <pthread.h>
#include <errno.h>		/* to pick up real defn of thread-safe errno */

#define LOCK_T pthread_mutex_t
#define THREAD_T pthread_t
#define COND_T pthread_cond_t
#define ONCE_T pthread_once_t
#define THREAD_STATE_KEY_T pthread_key_t

#define ONCE_INIT PTHREAD_ONCE_INIT

#define INIT_LOCK(LV) pthread_mutex_init(&(LV),NULL)
#define INIT_COND(CV) pthread_cond_init(&(CV),NULL)
#define STATE_KEY_INIT(SKV,FFN) pthread_key_create(&(SKV),FFN)
#define SET_TO_NULL_THREAD(TV) (TV)=0
#define SET_THREAD_TO_SELF(TV) (TV)=pthread_self()
#define THREAD_IS_SELF(TV) pthread_equal(TV,pthread_self())
#define FORK_THREAD(TV,FN,ARG) pthread_create(&(TV),NULL,FN,ARG)
#define GET_PER_THREAD_STATE(K) pthread_getspecific(K)
#define SET_PER_THREAD_STATE(K,V) pthread_setspecific(K,V)
#define GET_LOCK(LV) pthread_mutex_lock(&(LV))
#define GET_LOCK_P(LVP) pthread_mutex_lock(LVP)
#define TRY_LOCK(LV) pthread_mutex_trylock(&(LV))
#define REL_LOCK(LV) pthread_mutex_unlock(&(LV))
#define REL_LOCK_P(LVP) pthread_mutex_unlock(LVP)
#define WAIT_COND(CV,LV) pthread_cond_wait(&(CV),&(LV))
#define RUN_ONCE(OV,FN) pthread_once(&(OV),FN)
#define SIGNAL_COND(CV) pthread_cond_signal(&CV)

#define THREAD_PRINTF_FMT "%lx"
#define THREAD_PRINTF_ARG(TV) (TV)

#define _THREADS_IMPLEMENTATION 0xdeadbeef
#endif /* MIT_PTHREADS */

#ifdef DECOSF1_PTHREADS

#include <pthread.h>
#include <errno.h>

#define LOCK_T pthread_mutex_t
#define THREAD_T pthread_t
#define COND_T pthread_cond_t
#define ONCE_T pthread_once_t
#define THREAD_STATE_KEY_T pthread_key_t

#define ONCE_INIT {0,0,0}

#define INIT_LOCK(LV) pthread_mutex_init(&(LV),pthread_mutexattr_default)
#define INIT_COND(CV) pthread_cond_init(&(CV),pthread_condattr_default)
#define STATE_KEY_INIT(SKV,FFN) pthread_keycreate(&(SKV),FFN)
#define SET_TO_NULL_THREAD(TV) bzero((char *)&(TV),sizeof(pthread_t))
#define SET_THREAD_TO_SELF(TV) {pthread_t _tmp=pthread_self();\
				bcopy((char*)&_tmp,(char*)&(TV),sizeof(pthread_t));}
#define THREAD_IS_SELF(TV) pthread_equal(TV,pthread_self())
#define FORK_THREAD(TV,FN,ARG) pthread_create(&(TV),pthread_attr_default,FN,ARG)
#ifdef __GNUC__
#define GET_PER_THREAD_STATE(K) ({pthread_addr_t _tmp;pthread_getspecific(K,&_tmp);_tmp;})
#else
static pthread_addr_t _stupid_thread_getspecific_helper(k)
   pthread_key_t k; { pthread_addr_t _tmp; pthread_getspecific(k,&_tmp); return _tmp; }
#define GET_PER_THREAD_STATE(K) _stupid_thread_getspecific_helper(K)
#endif /* __GNUC__ */
#define SET_PER_THREAD_STATE(K,V) pthread_setspecific(K,V)
#define GET_LOCK(LV) pthread_mutex_lock(&(LV))
#define GET_LOCK_P(LVP) pthread_mutex_lock(LVP)
#define TRY_LOCK(LV) pthread_mutex_trylock(&(LV))
#define REL_LOCK(LV) pthread_mutex_unlock(&(LV))
#define REL_LOCK_P(LVP) pthread_mutex_unlock(LVP)
#define WAIT_COND(CV,LV) pthread_cond_wait(&(CV),&(LV))
#define RUN_ONCE(OV,FN) pthread_once(&(OV),FN)
#define SIGNAL_COND(CV) pthread_cond_signal(&CV)

#define THREAD_PRINTF_FMT "<%d,%d,%d>"
#define THREAD_PRINTF_ARG(TV) (TV).field1,(TV).field2,(TV).field3

#ifdef _THREADS_IMPLEMENTATION
bogus -- more than one threads implementation selected. Make up your mind!
#endif /* _THREADS_IMPLEMENTATION */

#define _THREADS_IMPLEMENTATION 0x0decfade
#endif /* DECOSF1_PTHREADS */

#ifdef DCE_PTHREADS

#ifdef _THREADS_IMPLEMENTATION
bogus -- more than one threads implementation selected. Make up your mind!
#endif /* _THREADS_IMPLEMENTATION */

#define _THREADS_IMPLEMENTATION 0xbeadface
#endif /* DCE_PTHREADS */

#ifdef IRIX_THREADS

#ifdef _THREADS_IMPLEMENTATION
bogus -- more than one threads implementation selected. Make up your mind!
#endif /* _THREADS_IMPLEMENTATION */

#define _THREADS_IMPLEMENTATION 0xfacedead
#endif /* IRIX_THREADS */

#ifdef MACH_CTHREADS

#ifdef _THREADS_IMPLEMENTATION
bogus -- more than one threads implementation selected. Make up your mind!
#endif /* _THREADS_IMPLEMENTATION */

#define _THREADS_IMPLEMENTATION 0xdeaddead
#endif /* MACH_CTHREADS */


#ifndef _THREADS_IMPLEMENTATION
bogus bogus bogus!! You did not tell me what threads implementation to use!!
#endif /* _THREADS_IMPLEMENTATION */

#endif /* __pqthreads_h_ */

