Index: cygwin/cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.21
diff -u -p -r1.21 cygwin.din
--- cygwin.din	2001/03/05 06:28:23	1.21
+++ cygwin.din	2001/03/16 14:19:35
@@ -1099,6 +1099,16 @@ cygwin32_internal = cygwin_internal
 @PTH_ALLOW@pthread_mutex_trylock
 @PTH_ALLOW@pthread_mutex_unlock
 @PTH_ALLOW@pthread_mutex_destroy
+@PTH_ALLOW@pthread_cond_init
+@PTH_ALLOW@pthread_cond_destroy
+@PTH_ALLOW@pthread_cond_broadcast
+@PTH_ALLOW@pthread_cond_signal
+@PTH_ALLOW@pthread_cond_wait
+@PTH_ALLOW@pthread_cond_timedwait
+@PTH_ALLOW@pthread_condattr_init
+@PTH_ALLOW@pthread_condattr_destroy
+@PTH_ALLOW@pthread_condattr_getpshared
+@PTH_ALLOW@pthread_condattr_setpshared
 @PTH_ALLOW@sem_init
 @PTH_ALLOW@sem_destroy
 @PTH_ALLOW@sem_wait
Index: cygwin/pthread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/pthread.cc,v
retrieving revision 1.3
diff -u -p -r1.3 pthread.cc
--- pthread.cc	2000/09/04 17:52:42	1.3
+++ pthread.cc	2001/03/16 14:19:35
@@ -171,6 +171,67 @@ pthread_mutex_destroy (pthread_mutex_t *
   return __pthread_mutex_destroy (mutex);
 }
 
+/* Synchronisation */
+
+int
+pthread_cond_destroy(pthread_cond_t *cond)
+{
+  return  __pthread_cond_destroy (cond);
+}
+
+int
+pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+  return __pthread_cond_init (cond, attr);
+}
+
+int
+pthread_cond_signal(pthread_cond_t *cond)
+{
+  return __pthread_cond_signal (cond);
+}
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+  return __pthread_cond_broadcast (cond);
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t *cond,
+	 pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+  return __pthread_cond_timedwait (cond, mutex, abstime);
+}
+
+int
+pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+  return __pthread_cond_wait (cond, mutex);
+}
+
+int
+pthread_condattr_init(pthread_condattr_t *condattr)
+{
+  return __pthread_condattr_init (condattr);
+}
+
+int
+pthread_condattr_destroy(pthread_condattr_t *condattr)
+{
+  return __pthread_condattr_destroy (condattr);
+}
+
+int
+pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
+{
+  return __pthread_condattr_getpshared (attr, pshared);
+}
+
+int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
+{
+  return __pthread_condattr_setpshared (attr, pshared);
+}
+
 /* Semaphores */
 int
 sem_init (sem_t * sem, int pshared, unsigned int value)
Index: cygwin/thread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.16
diff -u -p -r1.16 thread.cc
--- thread.cc	2001/02/20 02:53:55	1.16
+++ thread.cc	2001/03/16 14:19:37
@@ -63,6 +63,13 @@ extern int threadsafe;
   if (!item) return EINVAL; \
   CHECKHANDLE (EINVAL, 0);
 
+#define GETCOND(n) \
+  SetResourceLock (LOCK_COND_LIST, READ_LOCK, n); \
+  CondItem *item=user_data->threadinterface->GetCond (cond); \
+  ReleaseResourceLock (LOCK_COND_LIST, READ_LOCK, n); \
+  if (!item) return EINVAL; \
+  CHECKHANDLE (EINVAL, 0);
+
 #define CHECKITEM(rn, rm, fn) \
   if (!item) { \
     ReleaseResourceLock (rn, rm, fn); \
@@ -387,6 +394,13 @@ MTinterface::GetSemaphore (sem_t * sp)
   return (SemaphoreItem *) Find (sp, &CmpPthreadObj, index, &semalist);
 }
 
+CondItem *
+MTinterface::GetCond (pthread_cond_t * mp)
+{
+  AssertResourceOwner (LOCK_COND_LIST, READ_LOCK);
+  int index = 0;
+  return (CondItem *) Find (mp, &CmpPthreadObj, index, &condlist);
+}
 
 void
 MTitem::Destroy ()
@@ -455,7 +469,83 @@ SemaphoreItem::TryWait ()
   return WaitForSingleObject (win32_obj_id, 0);
 }
 
+/* Condition Items */
+CondItem *
+MTinterface::CreateCond (pthread_cond_t * cond, const pthread_condattr_t * attr)
+{
+  AssertResourceOwner (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK);
+
+  int i = FindNextUnused (&condlist);
+
+  CondItem *item = (CondItem *) GetItem (i, &condlist);
+  if (!item)
+    item = (CondItem *) SetItem (i, new CondItem (), &condlist);
+  if (!item)
+    system_printf ("cond creation failed");
+  item->used = true;
+  item->shared = attr->shared;
+  item->mutexitem=NULL;
+  item->waiting=0;
+
+  item->win32_obj_id = ::CreateEvent (&sec_none_nih, 
+	false, /* auto signal reset - which I think is pthreads like ? */
+	false, /* start non signaled */
+	NULL /* no name */ );
+
+
+  CHECKHANDLE (NULL, 1);
+
+  *cond = (pthread_cond_t) item->win32_obj_id;
+
+  return item;
+}
+
+
+int
+CondItem::Signal ()
+{
+  return !PulseEvent(win32_obj_id);
+}
+
+int
+CondItem::Wait ()
+{
+  return SignalObjectAndWait (mutexitem->win32_obj_id, win32_obj_id, INFINITE, false);
+}
+
+int
+CondItem::TimedWait (DWORD dwMilliseconds)
+{
+  return SignalObjectAndWait (mutexitem->win32_obj_id, win32_obj_id, dwMilliseconds, false);
+}
+
+int
+CondItem::BroadCast ()
+{
+  if (!mutexitem)
+    return 0;
+  PulseEvent(win32_obj_id);
+  while (InterlockedDecrement(&waiting)!=0)
+    PulseEvent(win32_obj_id);
+  mutexitem=NULL;
+  return 0;
+}
 
+/*
+int
+MutexItem::TryLock ()
+{
+  return WaitForSingleObject (win32_obj_id, 0);
+}
+
+int
+MutexItem::UnLock ()
+{
+  return ReleaseMutex (win32_obj_id);
+}
+
+*/
+
 //////////////////////////  Pthreads
 
 void *
@@ -678,6 +768,145 @@ __pthread_getspecific (pthread_key_t */*
   NOT_IMP ("_p_key_getsp\n");
 }
 
+/* Thread synchronisation */
+
+int
+__pthread_cond_destroy(pthread_cond_t *cond)
+{
+  SetResourceLock (LOCK_COND_LIST, READ_LOCK | WRITE_LOCK, "__pthread_cond_destroy");
+
+  CondItem *item = MT_INTERFACE->GetCond (cond);
+
+  CHECKITEM (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+  item->Destroy ();
+
+  MT_INTERFACE->ReleaseItem (item);
+
+  ReleaseResourceLock (LOCK_COND_LIST, READ_LOCK | WRITE_LOCK, "__pthread_cond_destroy")
+;
+  return 0;
+}
+
+int
+__pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+  if (attr && (attr->valid != 0xf341))
+    return EINVAL;
+  SetResourceLock (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+  CondItem *item = MT_INTERFACE->CreateCond (cond, attr);
+
+  CHECKITEM (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+  ReleaseResourceLock (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+  return 0;
+
+}
+
+int __pthread_cond_broadcast(pthread_cond_t *cond)
+{
+  GETCOND("_pthread_cond_lock");
+  
+  item->BroadCast();
+
+  return 0;
+}
+
+int __pthread_cond_signal(pthread_cond_t *cond)
+{
+  GETCOND("_pthread_cond_lock");
+
+  item->Signal();
+
+  return 0;
+}
+
+int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+  if (!abstime)
+    return EINVAL;
+  SetResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+  MutexItem* mutexitem=user_data->threadinterface->GetMutex (mutex);
+  ReleaseResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+  if (!mutexitem) return EINVAL;
+  if (!mutexitem->HandleOke ())
+  {
+    return EINVAL;
+  }
+  GETCOND("_pthread_cond_lock");
+  if (item->mutexitem && (item->mutexitem != mutexitem))
+    return EINVAL;
+
+  item->mutexitem=mutexitem;
+  InterlockedIncrement(&item->waiting);
+  item->TimedWait(abstime->tv_sec*1000);
+  mutexitem->Lock();
+  if (InterlockedDecrement(&item->waiting)==0)
+    item->mutexitem=NULL;
+
+  return 0;
+}
+
+int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{ 
+  SetResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock"); 
+  MutexItem* mutexitem=user_data->threadinterface->GetMutex (mutex); 
+  ReleaseResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock"); 
+  if (!mutexitem) return EINVAL;  
+  if (!mutexitem->HandleOke ())
+  { 
+    return EINVAL; 
+  }
+  GETCOND("_pthread_cond_lock");
+  if (item->mutexitem && (item->mutexitem != mutexitem))
+    return EINVAL;
+  
+  item->mutexitem=mutexitem;
+  InterlockedIncrement(&item->waiting);
+  item->Wait();  
+  mutexitem->Lock();
+  if (InterlockedDecrement(&item->waiting)==0)
+    item->mutexitem=NULL;
+ 
+  return 0;
+}
+
+int
+__pthread_condattr_init (pthread_condattr_t * condattr)
+{
+  condattr->shared = 0;
+  condattr->valid  = 0xf341; /* Roberts magic number */
+  return 0;
+}
+
+int
+__pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
+{
+  if (!attr || (attr->valid != 0xf341))
+    return EINVAL;
+  *pshared = attr->shared;
+  return 0;
+}
+
+int
+__pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
+{
+  if (!attr || (attr->valid != 0xf341) || (pshared <0) || (pshared > 1 ))
+    return EINVAL;
+  attr->shared = pshared;
+  return 0;
+}
+
+int
+__pthread_condattr_destroy (pthread_condattr_t * condattr)
+{
+  if (!condattr || (condattr->valid != 0xf341))
+      return EINVAL;
+  condattr->valid=0;
+  return 0;
+}
+
 /* Thread signal */
 int
 __pthread_kill (pthread_t * thread, int sig)
@@ -693,7 +922,6 @@ __pthread_kill (pthread_t * thread, int 
 
 // unlock myself
   return rval;
-
 }
 
 int
@@ -953,6 +1181,46 @@ extern "C"
     return -1;
   }
   int __pthread_mutex_destroy (pthread_mutex_t *)
+  {
+    return -1;
+  }
+  int __pthread_cond_destroy(pthread_cond_t *)
+  {
+    return -1;
+  }
+  int __pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *)
+  {
+    return -1;
+  }
+  int __pthread_cond_signal(pthread_cond_t *)
+  {
+    return -1;
+  }
+  int __pthread_cond_broadcast(pthread_cond_t *)
+  {
+    return -1;
+  }
+  int __pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *)
+  {
+    return -1;
+  }
+  int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *)
+  {
+    return -1;
+  }
+  int __pthread_condattr_init (pthread_condattr_t *)
+  {
+    return -1;
+  }
+  int __pthread_condattr_destroy (pthread_condattr_t *)
+  {
+    return -1;
+  }
+  int __pthread_condattr_getpshared (pthread_condattr_t *, int *)
+  {
+    return -1;
+  }
+  int __pthread_condattr_setpshared (pthread_condattr_t *, int)
   {
     return -1;
   }
Index: cygwin/thread.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.h,v
retrieving revision 1.8
diff -u -p -r1.8 thread.h
--- thread.h	2000/10/16 23:55:57	1.8
+++ thread.h	2001/03/16 14:19:37
@@ -20,6 +20,7 @@ details. */
 #define LOCK_THREAD_LIST 5
 #define LOCK_MUTEX_LIST  6
 #define LOCK_SEM_LIST    7
+#define LOCK_COND_LIST   8
 
 #define WRITE_LOCK 1
 #define READ_LOCK  2
@@ -190,6 +191,17 @@ public:
   int TryWait ();
 };
 
+class CondItem: public MTitem
+{
+public:
+  int shared;
+  LONG waiting;
+  MutexItem *mutexitem;
+  int Wait ();
+  int TimedWait (DWORD dwMilliseconds);
+  int BroadCast ();
+  int Signal ();
+};
 
 typedef struct
 {
@@ -226,6 +238,10 @@ public:
   SemaphoreItem *CreateSemaphore (sem_t *, int, int);
   SemaphoreItem *GetSemaphore (sem_t * t);
 
+  // Condition functions
+  CondItem *CreateCond (pthread_cond_t *, const pthread_condattr_t *); 
+  CondItem *GetCond (pthread_cond_t *);
+
 private:
   // General Administration
   MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *);
@@ -237,6 +253,7 @@ private:
   MTList threadlist;
   MTList mutexlist;
   MTList semalist;
+  MTList condlist;
 };
 
 
@@ -274,6 +291,17 @@ int __pthread_key_delete (pthread_key_t 
 int __pthread_setspecific (pthread_key_t * key, const void *value);
 void *__pthread_getspecific (pthread_key_t * key);
 
+/* Thead synchroniation */
+int __pthread_cond_destroy(pthread_cond_t *cond);
+int __pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
+int __pthread_cond_signal(pthread_cond_t *cond);
+int __pthread_cond_broadcast(pthread_cond_t *cond);
+int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
+int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int __pthread_condattr_init (pthread_condattr_t * condattr);
+int __pthread_condattr_destroy (pthread_condattr_t * condattr);
+int __pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared);
+int __pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared);
 
 /* Thread signal */
 int __pthread_kill (pthread_t * thread, int sig);
Index: cygwin/include/pthread.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/pthread.h,v
retrieving revision 1.2
diff -u -p -r1.2 pthread.h
--- pthread.h	2000/05/08 22:38:07	1.2
+++ pthread.h	2001/03/16 14:19:38
@@ -23,6 +23,16 @@ extern "C"
 
 #define TFD(n) void*(*n)(void*)
 
+/* Defines. (These are correctly defined here as per
+   http://www.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html */
+
+/* FIXME: this should allocate a new cond variable, and return the value  that
+ would normally be written to the passed parameter of pthread_cond_init(lvalue, NULL); */
+// #define PTHREAD_COND_INITIALIZER 0
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED  1
+
 typedef int pthread_t;
 typedef int pthread_mutex_t;
 typedef int sem_t;
@@ -43,12 +53,35 @@ typedef struct pthread_mutexattr
   }
 pthread_mutexattr_t;
 
+typedef struct pthread_condattr
+  {
+    int shared;
+    int valid;
+  }
+pthread_condattr_t;
+
+typedef int pthread_cond_t;
+
 /*  ThreadCreation */
 int pthread_create (pthread_t * thread, const pthread_attr_t * attr, TFD (function), void *arg);
 int pthread_attr_init (pthread_attr_t * attr);
 int pthread_attr_destroy (pthread_attr_t * attr);
 int pthread_attr_setstacksize (pthread_attr_t * attr, size_t size);
 int pthread_attr_getstacksize (pthread_attr_t * attr, size_t * size);
+
+/* Condition variables */
+int   pthread_cond_broadcast(pthread_cond_t *);
+int   pthread_cond_destroy(pthread_cond_t *);
+int   pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
+int   pthread_cond_signal(pthread_cond_t *);
+int   pthread_cond_timedwait(pthread_cond_t *, 
+          pthread_mutex_t *, const struct timespec *);
+int   pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int   pthread_condattr_destroy(pthread_condattr_t *);
+int   pthread_condattr_getpshared(const pthread_condattr_t *, int *);
+int   pthread_condattr_init(pthread_condattr_t *);
+int   pthread_condattr_setpshared(pthread_condattr_t *, int);
+
 
 /* Thread Control */
 int pthread_detach (pthread_t thread);
