#include "config_xor.h"

#include "sh_pthread.h"

#ifdef HAVE_PTHREAD
SH_MUTEX_INIT(mutex_skey,   PTHREAD_MUTEX_INITIALIZER);
SH_MUTEX_INIT(mutex_resolv, PTHREAD_MUTEX_INITIALIZER);
SH_MUTEX_INIT(mutex_pwent,  PTHREAD_MUTEX_INITIALIZER);
SH_MUTEX_INIT(mutex_readdir,PTHREAD_MUTEX_INITIALIZER);

void sh_pthread_mutex_unlock (void *arg)
{
  (void) pthread_mutex_unlock ((pthread_mutex_t *)arg);
  return;
}


/**
 * libxml2 threads.c: set of generic threading related routines 
 *
 * Gary Pennington <Gary.Pennington@uk.sun.com>
 * daniel@veillard.com
 */

void sh_InitRMutex(struct sh_RMutex * tok)
{
  pthread_mutex_init(&tok->lock, NULL);
  tok->held = 0;
  tok->waiters = 0;
  pthread_cond_init(&tok->cv, NULL);

  return;
}

void sh_RMutexLock(struct sh_RMutex * tok)
{
  if (tok == NULL)
    return;

  pthread_mutex_lock(&tok->lock);
  if (tok->held) {
    if (pthread_equal(tok->tid, pthread_self())) {
      tok->held++;
      pthread_mutex_unlock(&tok->lock);
      return;
    } else {
      tok->waiters++;
      while (tok->held)
	pthread_cond_wait(&tok->cv, &tok->lock);
      tok->waiters--;
    }
  }
  tok->tid = pthread_self();
  tok->held = 1;
  pthread_mutex_unlock(&tok->lock);
}

void sh_RMutexUnlock(void * arg)
{
  struct sh_RMutex * tok = (struct sh_RMutex *) arg;

  if (tok == NULL)
    return;
    
  pthread_mutex_lock(&tok->lock);
  tok->held--;
  if (tok->held == 0) {
    if (tok->waiters)
      pthread_cond_signal(&tok->cv);
    tok->tid = 0;
  }
  pthread_mutex_unlock(&tok->lock);
}
#endif
