From 97cb4b33462735b93ac9522df6bf4d43d0b7fe71 Mon Sep 17 00:00:00 2001
From: bje <bje>
Date: Sun, 4 Oct 1998 18:32:15 +0000
Subject: 1998-10-05  Ben Elliston  <bje@cygnus.com> 	* global.c
 (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h. 	* pthread.h
 (PTHREAD_MUTEX_INITIALIZER): Define. 	(pthread_mutex_t): Reimplement as a
 struct containing a valid 	flag. If the flag is ever down upon entry to a
 mutex operation, 	we call pthread_mutex_create() to initialise the
 object. This 	fixes the problem of how to handle statically initialised
 objects 	that can't call InitializeCriticalSection() due to their
 context. 	* mutex.c (pthread_mutex_init): Set valid flag. 
 (pthread_mutex_destroy): Clear valid flag. 	(pthread_mutex_lock): Check
 and handle the valid flag. 	(pthread_mutex_unlock): Likewise. 
 (pthread_mutex_trylock): Likewise. 	* tests/mutex3.c: New file; test for
 the static initialisation 	macro. Passes.

---
 ChangeLog      | 20 ++++++++++++++++++++
 global.c       |  3 ---
 mutex.c        | 30 +++++++++++++++++++++++++-----
 pthread.h      |  7 ++++++-
 tests/mutex3.c | 12 ++++++++++++
 5 files changed, 63 insertions(+), 9 deletions(-)
 create mode 100644 tests/mutex3.c

diff --git a/ChangeLog b/ChangeLog
index cbabbdf..5934633 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+1998-10-05  Ben Elliston  <bje@cygnus.com>
+
+	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
+
+	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
+	(pthread_mutex_t): Reimplement as a struct containing a valid
+	flag. If the flag is ever down upon entry to a mutex operation,
+	we call pthread_mutex_create() to initialise the object. This
+	fixes the problem of how to handle statically initialised objects
+	that can't call InitializeCriticalSection() due to their context.
+
+	* mutex.c (pthread_mutex_init): Set valid flag.
+	(pthread_mutex_destroy): Clear valid flag.
+	(pthread_mutex_lock): Check and handle the valid flag.
+	(pthread_mutex_unlock): Likewise.
+	(pthread_mutex_trylock): Likewise.
+
+	* tests/mutex3.c: New file; test for the static initialisation
+	macro. Passes.
+	
 1998-10-04  Ben Elliston  <bje@cygnus.com>
 
 	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
diff --git a/global.c b/global.c
index 0835f48..6d55581 100644
--- a/global.c
+++ b/global.c
@@ -33,9 +33,6 @@ const int _pthread_cancel_deferred     = 1;
 
 /* Declare variables which are global to all threads in the process. */
 
-/* FIXME: This is temporary. */
-#define PTHREAD_MUTEX_INITIALIZER {0}
-
 pthread_mutex_t _pthread_table_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 DWORD _pthread_threads_count = 0;
diff --git a/mutex.c b/mutex.c
index aaf4ff4..03f3f48 100644
--- a/mutex.c
+++ b/mutex.c
@@ -19,7 +19,10 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
     }
 
   /* Create a critical section. */
-  InitializeCriticalSection(mutex);
+  InitializeCriticalSection(&mutex->cs);
+
+  /* Mark as valid. */
+  mutex->valid = 1;
 
   return 0;
 }
@@ -32,7 +35,11 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
       return EINVAL;
     }
 
-  DeleteCriticalSection(mutex);
+  DeleteCriticalSection(&mutex->cs);
+  
+  /* Mark as invalid. */
+  mutex->valid = 0;
+
   return 0;
 }
 
@@ -59,14 +66,22 @@ pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
 int
 pthread_mutex_lock(pthread_mutex_t *mutex)
 {
-  EnterCriticalSection(mutex);
+  if (!mutex->valid)
+    {
+      pthread_mutex_init(mutex, NULL);
+    }
+  EnterCriticalSection(&mutex->cs);
   return 0;
 }
 
 int
 pthread_mutex_unlock(pthread_mutex_t *mutex)
 {
-  LeaveCriticalSection(mutex);
+  if (!mutex->valid)
+    {
+      return EINVAL;
+    }
+  LeaveCriticalSection(&mutex->cs);
   return 0;
 }
 
@@ -87,5 +102,10 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
       return EINVAL;
     }
 
-  return (TryEnterCriticalSection(mutex) != TRUE) ? EBUSY : 0;
+  if (!mutex->valid)
+    {
+      pthread_mutex_init(mutex, NULL);
+    }
+
+  return (TryEnterCriticalSection(&mutex->cs) != TRUE) ? EBUSY : 0;
 }
diff --git a/pthread.h b/pthread.h
index 5c31af2..e9278c2 100644
--- a/pthread.h
+++ b/pthread.h
@@ -74,8 +74,13 @@ struct timespec {
    pointer to an object in memory. */
 #define PTHREAD_CANCELED            ((void *) 1)
 
+#define PTHREAD_MUTEX_INITIALIZER {0 /* ignore internals */ }
+
 typedef struct _pthread * pthread_t;
-typedef CRITICAL_SECTION pthread_mutex_t;
+typedef struct {
+	int valid;
+	CRITICAL_SECTION cs;
+} pthread_mutex_t;
 typedef DWORD pthread_key_t;
 
 
diff --git a/tests/mutex3.c b/tests/mutex3.c
new file mode 100644
index 0000000..2bb6106
--- /dev/null
+++ b/tests/mutex3.c
@@ -0,0 +1,12 @@
+#include <pthread.h>
+
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int
+main()
+{
+  pthread_mutex_lock(&mutex);
+  /* do stuff */
+  pthread_mutex_unlock(&mutex);
+  return 0;
+}
-- 
cgit v1.2.3