OSDN Git Service

* spinlock.h: New file.
authorcgf <cgf>
Sun, 14 Mar 2010 04:34:34 +0000 (04:34 +0000)
committercgf <cgf>
Sun, 14 Mar 2010 04:34:34 +0000 (04:34 +0000)
(spinlock): New class.
* shared.cc: Include spinlock.h.
(memory_init): Use new spinlock methods rather than roll-your-own.  Time out
after ten seconds if shared_mem_inited is not initialized.
* sync.h: Update copyright.  Remove vanity attribution.
* sigproc.cc (sigproc_terminate): Avoid attempts to kill the signal thread
while we're still initializing or suffer a deadlock.

winsup/cygwin/ChangeLog
winsup/cygwin/shared.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/spinlock.h [new file with mode: 0644]
winsup/cygwin/sync.h

index e476c7e..c571391 100644 (file)
@@ -1,3 +1,16 @@
+2010-03-13  Christopher Faylor  <me+cygwin@cgf.cx>
+
+       * spinlock.h: New file.
+       (spinlock): New class.
+       * shared.cc: Include spinlock.h.
+       (memory_init): Use new spinlock methods rather than roll-your-own.
+       Time out after ten seconds if shared_mem_inited is not initialized.
+
+       * sync.h: Update copyright.  Remove vanity attribution.
+
+       * sigproc.cc (sigproc_terminate): Avoid attempts to kill the signal
+       thread while we're still initializing or suffer a deadlock.
+
 2010-03-12  Christopher Faylor  <me+cygwin@cgf.cx>
 
        Throughout change all calls of low_priority_sleep (0) to yield ().
index fcca6f4..6e166f3 100644 (file)
@@ -23,6 +23,7 @@ details. */
 #include "registry.h"
 #include "cygwin_version.h"
 #include "pwdgrp.h"
+#include "spinlock.h"
 #include "ntdll.h"
 #include <alloca.h>
 #include <wchar.h>
@@ -418,40 +419,28 @@ memory_init (bool init_cygheap)
     }
 
   /* Initialize general shared memory under spinlock control */
-  for (;;)
-    {
-      LONG smi = InterlockedExchange (&shared_mem_inited, -1);
-      if (smi < 0)
-       {
-         yield ();
-         continue;
-       }
-
-      if (!smi)
-       /* Initialize installation root dir */
-       init_installation_root ();
-
-      cygwin_shared = (shared_info *) open_shared (L"shared",
-                                                  CYGWIN_VERSION_SHARED_DATA,
-                                                  cygwin_shared_h,
-                                                  sizeof (*cygwin_shared),
-                                                  SH_CYGWIN_SHARED);
-      heap_init ();
-
-      if (!smi)
-       {
-         cygwin_shared->initialize ();
-         /* Defer debug output printing the installation root and installation key
-            up to this point.  Debug output except for system_printf requires
-            the global shared memory to exist. */
-         debug_printf ("Installation root: <%W> key: <%S>",
-                       installation_root, &installation_key);
-         smi = 1;
-       }
-
-      InterlockedExchange (&shared_mem_inited, smi);
-      break;
-    }
+  {
+    spinlock smi (shared_mem_inited, 10000);
+    if (!smi)
+      init_installation_root ();       /* Initialize installation root dir */
+
+    cygwin_shared = (shared_info *) open_shared (L"shared",
+                                                CYGWIN_VERSION_SHARED_DATA,
+                                                cygwin_shared_h,
+                                                sizeof (*cygwin_shared),
+                                                SH_CYGWIN_SHARED);
+    heap_init ();
+
+    if (!smi)
+      {
+       cygwin_shared->initialize ();
+       /* Defer debug output printing the installation root and installation key
+          up to this point.  Debug output except for system_printf requires
+          the global shared memory to exist. */
+       debug_printf ("Installation root: <%W> key: <%S>",
+                     installation_root, &installation_key);
+      }
+  }
   user_shared_create (false);
 }
 
index 9408b0c..e846903 100644 (file)
@@ -494,7 +494,9 @@ sigproc_terminate (exit_states es)
 {
   exit_states prior_exit_state = exit_state;
   exit_state = es;
-  if (prior_exit_state >= ES_FINAL)
+  if (!cygwin_finished_initializing)
+    sigproc_printf ("don't worry about signal thread");
+  else if (prior_exit_state >= ES_FINAL)
     sigproc_printf ("already performed");
   else
     {
diff --git a/winsup/cygwin/spinlock.h b/winsup/cygwin/spinlock.h
new file mode 100644 (file)
index 0000000..abf723a
--- /dev/null
@@ -0,0 +1,40 @@
+/* spinlock.h: Header file for cygwin time-sensitive synchronization primitive.
+
+   Copyright 2010 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef _SPINLOCK_H
+#define _SPINLOCK_H
+
+#include "hires.h"
+
+class spinlock
+{
+  LONG *locker;
+  LONG val;
+public:
+  spinlock (LONG& locktest, LONGLONG timeout):
+    locker (&locktest)
+  {
+    if ((val = locktest) == 1)
+      return;
+    LONGLONG then = gtod.msecs ();
+    for (;;)
+      {
+       if ((val = InterlockedExchange (locker, -1)) != -1
+           || (gtod.msecs () - then) >= timeout)
+         break;
+       yield ();
+      }
+  }
+  ~spinlock () {InterlockedExchange (locker, 1);}
+  operator LONG () const {return val;}
+};
+
+#endif /*_SPINLOCK_H*/
+
index dfe2c39..5d66b97 100644 (file)
@@ -1,8 +1,6 @@
 /* sync.h: Header file for cygwin synchronization primitives.
 
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
-
-   Written by Christopher Faylor <cgf@cygnus.com>
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
 
 This file is part of Cygwin.