/*
 * This include file handles fixups needed for the DECthreads implementation
 * of the pthread library definitions  Files that include this file will
 * use the special macros it defines in order to be compatible with
 * both the Posix 1003.1c standard interface the old 1003.4a draft standard.
 */
#ifdef __ALPHA
#define pthread_attr_init PTHREAD_ATTR_INIT
#define pthread_attr_setinheritsched PTHREAD_ATTR_SETINHERITSCHED
#define pthread_attr_setschedparam PTHREAD_ATTR_SETSCHEDPARAM
#define pthread_attr_setschedpolicy PTHREAD_ATTR_SETSCHEDPOLICY
#define pthread_attr_setstacksize PTHREAD_ATTR_SETSTACKSIZE
#define pthread_cancel PTHREAD_CANCEL
#define pthread_cond_destroy PTHREAD_COND_DESTROY
#define pthread_cond_init PTHREAD_COND_INIT
#define pthread_cond_signal PTHREAD_COND_SIGNAL
#define pthread_cond_signal_int_np PTHREAD_COND_SIGNAL_INT_NP
#define pthread_cond_timedwait PTHREAD_COND_TIMEDWAIT
#define pthread_cond_wait PTHREAD_COND_WAIT
#define pthread_create PTHREAD_CREATE
#define pthread_detach PTHREAD_DETACH
#define pthread_exc_fetch_fp_np PTHREAD_EXC_FETCH_FP_NP
#define pthread_exc_handler_np PTHREAD_EXC_HANDLER_NP
#define pthread_exc_pop_ctx_np PTHREAD_EXC_POP_CTX_NP
#define pthread_exc_push_ctx_np PTHREAD_EXC_PUSH_CTX_NP
#define pthread_exc_savecontext_np PTHREAD_EXC_SAVECONTEXT_NP
#define pthread_get_expiration_np PTHREAD_GET_EXPIRATION_NP
#define pthread_getspecific PTHREAD_GETSPECIFIC
#define pthread_join32 PTHREAD_JOIN32
#define pthread_key_create PTHREAD_KEY_CREATE
#define pthread_lock_global_np PTHREAD_LOCK_GLOBAL_NP
#define pthread_mutex_init PTHREAD_MUTEX_INIT
#define pthread_mutex_lock PTHREAD_MUTEX_LOCK
#define pthread_mutex_unlock PTHREAD_MUTEX_UNLOCK
#define pthread_once PTHREAD_ONCE
#define pthread_setspecific PTHREAD_SETSPECIFIC
#define pthread_unlock_global_np PTHREAD_UNLOCK_GLOBAL_NP
#endif
#ifdef __GNUC__
#define pthread_self pthread_self_hidden
#endif
#include <pthread.h>
#ifdef __DECC
#include <reentrancy.h>
#endif

#ifndef PTHREAD_USE_D4
#ifndef PTHREAD_EXPLICIT_SCHED
/* 
 * When PTHREAD_EXPLICIT_SCHED not defined, assume we are using older draft 4 
 * pthread.h and define standard symbol to use in conditional tests.
 */
#define PTHREAD_USE_D4
#endif
#endif
/*
 * For some reason, the re-defines of malloc and free don't have correspondin
 * entries in the shareable images, so undefine them.
 */
#if defined(VAXC) || defined(_GNUC_)
#ifdef malloc
#undef malloc
#endif
#ifdef free
#undef free
#endif
#ifdef realloc
#undef realloc
#endif
#endif
/*
 * If the c routines ever become thread-reentrant, null out these definitions.
 * As an intermediate step, we've made these dependant upon a global flag.
 */
int http_reentrant_c_rtl;
#ifdef VMS
#define LOCK_C_RTL if ( !http_reentrant_c_rtl ) pthread_lock_global_np();
#define UNLOCK_C_RTL if ( !http_reentrant_c_rtl ) pthread_unlock_global_np();
#else
#define LOCK_C_RTL
#define UNLOCK_C_RTL
#define LOCK_VMS_RTL
#define UNLOCK_VMS_RTL
#endif

int http_reentrant_vms_rtl;
#ifdef VMS
#define LOCK_VMS_RTL 
#define UNLOCK_VMS_RTL
#endif
/*
 * Set symbol that tserver_tcp.h uses to detect if pthread headers known.
 */
#define loaded_pthread_np 1
/*
 * Workaround GCCs problem with structure returned by pthread_self() function.
 */
#ifdef __GNUC__
#undef pthread_self
void pthread_self ( pthread_t * );
static pthread_t gcc_pthread_self() {
    pthread_t temp;
    pthread_self ( &temp );
    return temp;
}
#define pthread_self gcc_pthread_self
#endif

#ifdef PTHREAD_USE_D4
#include <errno.h>
#define INITIALIZE_MUTEX(a) pthread_mutex_init ( a, pthread_mutexattr_default )
#define INITIALIZE_CONDITION(a) pthread_cond_init(a,pthread_condattr_default)
#define INITIALIZE_THREAD_ATTR(a) pthread_attr_create ( a )
#define PTHREAD_ERR_NO(status) ((status)==(-1) ? errno : (status))
#define CREATE_KEY(key,init) pthread_keycreate(key,init)
#define DETACH_THREAD(t) pthread_detach(&t)
#define GET_SPECIFIC(key,lval) \
  if ( pthread_getspecific(key, (pthread_addr_t *) &lval) ) lval =  (void *) 0;
#ifndef _POSIX_4SOURCE
struct sched_param { int sched_priority; };
#endif
#define SET_ATTR_SCHEDPARAM(attr,param) \
  pthread_attr_setprio(attr,(param)->sched_priority)
#define SET_ATTR_SCHEDPOLICY(attr,policy) pthread_attr_setsched(attr,policy)
/*
 * Rename some macros to 1.c forms.
 */
#define PTHREAD_ONCE_INIT  pthread_once_init
#define PTHREAD_EXPLICIT_SCHED PTHREAD_DEFAULT_SCHED

#else
#define INITIALIZE_MUTEX(a) pthread_mutex_init ( a, NULL )
#define INITIALIZE_CONDITION(a) pthread_cond_init ( a, NULL )
#define INITIALIZE_THREAD_ATTR(a) pthread_attr_init ( a )
#define PTHREAD_ERR_NO(status) status
typedef void (*pthread_destructor_t)(void *);
typedef void *(*pthread_startroutine_t)(void *);
#define CREATE_KEY(key,init) pthread_key_create(key, init)
#define DETACH_THREAD(t) pthread_detach(t)
#define GET_SPECIFIC(key,lval) lval=pthread_getspecific(key);
#define SET_ATTR_SCHEDPARAM(attr,param) pthread_attr_setschedparam(attr,param)
#define SET_ATTR_SCHEDPOLICY(attr,policy) pthread_attr_setschedpolicy(attr,policy)
#endif
