OSDN Git Service

* cygtls.h (_threadinfo::call): Remove regparm declaration to work around
[pf3gnuchains/sourceware.git] / winsup / cygwin / sync.cc
index 7ef5dc8..dbc2630 100644 (file)
@@ -4,7 +4,7 @@
    which is intended to operate similarly to a mutex but attempts to
    avoid making expensive calls to the kernel.
 
-   Copyright 2000, 2001 Red Hat, Inc.
+   Copyright 2000, 2001, 2002 Red Hat, Inc.
 
    Written by Christopher Faylor <cgf@cygnus.com>
 
@@ -23,23 +23,27 @@ details. */
 #include "sync.h"
 #include "security.h"
 
-muto NO_COPY muto_start;
-
 #undef WaitForSingleObject
 
+DWORD NO_COPY muto::exiting_thread;
+
 /* Constructor */
-muto::muto (int inh, const char *s) : sync (0), visits(0), waiters(-1), tid (0), next (NULL)
+muto *
+muto::init (const char *s)
 {
+  waiters = -1;
   /* Create event which is used in the fallback case when blocking is necessary */
-  if (!(bruteforce = CreateEvent (inh ? &sec_all_nih : &sec_none_nih, FALSE, FALSE, name)))
+  if (!(bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL)))
     {
       DWORD oerr = GetLastError ();
       SetLastError (oerr);
-      return;
+      return NULL;
     }
   name = s;
+  return this;
 }
 
+#if 0 /* FIXME: Do we need this? mutos aren't destroyed until process exit */
 /* Destructor (racy?) */
 muto::~muto ()
 {
@@ -47,11 +51,12 @@ muto::~muto ()
     release ();
 
   HANDLE h = bruteforce;
-  h = NULL;
+  bruteforce = NULL;
   /* Just need to close the event handle */
   if (h)
     CloseHandle (h);
 }
+#endif
 
 /* Acquire the lock.  Argument is the number of milliseconds to wait for
    the lock.  Multiple visits from the same thread are allowed and should
@@ -64,6 +69,8 @@ int
 muto::acquire (DWORD ms)
 {
   DWORD this_tid = GetCurrentThreadId ();
+  if (exiting_thread)
+    return this_tid == exiting_thread;
 
   if (tid != this_tid)
     {
@@ -82,7 +89,7 @@ muto::acquire (DWORD ms)
         case, it is possible for a thread which is going to wait for bruteforce
         to wake up immediately.  It will then attempt to grab sync but will fail
         and go back to waiting.  */
-      while (tid != this_tid && (was_waiting || InterlockedExchange (&sync, 1) != 0))
+      if (tid != this_tid && (was_waiting || InterlockedExchange (&sync, 1) != 0))
        {
          switch (WaitForSingleObject (bruteforce, ms))
              {
@@ -106,6 +113,8 @@ int
 muto::release ()
 {
   DWORD this_tid = GetCurrentThreadId ();
+  if (exiting_thread)
+    return this_tid == exiting_thread;
 
   if (tid != this_tid || !visits)
     {
@@ -128,6 +137,12 @@ muto::release ()
   return 1;    /* success. */
 }
 
+bool
+muto::acquired ()
+{
+  return tid == GetCurrentThreadId ();
+}
+
 /* Call only when we're exiting.  This is not thread safe. */
 void
 muto::reset ()