]> sourceware.org Git - newlib-cygwin.git/commitdiff
* bsd_helper.cc (ipcexit_hookthread): Fix whitespace and handle leak.
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 6 Apr 2005 11:11:07 +0000 (11:11 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 6 Apr 2005 11:11:07 +0000 (11:11 +0000)
* bsd_mutex.cc: Include stdlib.h, sys/msg.h and sys/sem.h.
(mtx_init): Initialize lock counter to 0.
(_mtx_lock): Increment and log mutex lock counter.
(mtx_owned): Add winpid argument. Return true only if mutex is
actually owned by process winpid.
(_mtx_assert): Add winpid argument accordingly.
(_mtx_unlock): Log owner and lock count.
(MSLEEP_MUTEX): Remove.
(MSLEEP_SEM): Ditto.
(MSLEEP_EVENT): Ditto.
(msleep_event_name): Ditto.
(msleep_cs): New global critical section.
(msleep_cnt): New global variable indicating msleep record usage.
(msleep_max_cnt): New global variable indicating msleep record size.
(msleep_arr): New global pointer to msleep records.
(msleep_init): Initialize msleep_cs. Allocate msleep_arr array.
(_msleep): Rewrite using new msleep_cs/msleep_arr based thread
synchronization. Don't be shy with debug output.
(wakeup): Rewrite using new msleep_cs/msleep_arr based thread
synchronization.
* bsd_mutex.h (struct mtx): Add lock counter for better debugging.
(mtx_owned): Declare with winpid argument.
(_mtx_assert): Ditto.
(mtx_assert): Define with winpid argument.
* cygserver.cc (version): Remove.
(SERVER_VERSION): New define, decoupling server version information
from source code control system.
(print_version): Simplify printing server version.
* process.cc (process::process): Fix wrong bracketing (and handle leak).
(process::~process): Only try to close _signal_arrived if valid.
* sysv_sem.cc: Include sys/smallprint.h.
(semundo_clear): Define with additional struct thread pointer argument.
Accomodate throughout.
(SEMUNDO_LOCKASSERT): Define with winpid argument. Accomodate
throughout.
(struct sem_undo): Define un_proc as pid_t on Cygwin. Accomodate
throughout.
(seminit): Improve debugging by adding the semid to the mutex name.
(semget): Correctly print key value as 64 bit hex value in debug
output.
(semexit_myhook): Remove Cygwin specific unlocking of mutexes owned
by exiting process.  Keep semaphore global lock throughout whole
function to avoid races.
* sysv_shm.cc (GIANT_REQUIRED): Define empty on Cygwin. We know that
Giant is locked.

winsup/cygserver/ChangeLog
winsup/cygserver/bsd_helper.cc
winsup/cygserver/bsd_mutex.cc
winsup/cygserver/bsd_mutex.h
winsup/cygserver/cygserver.cc
winsup/cygserver/process.cc
winsup/cygserver/sysv_sem.cc
winsup/cygserver/sysv_shm.cc

index 9bf453acec54368c4670137f2b29916bf96f928e..06bd7aff669247f5dacff31e56d3ccc21a22aaad 100644 (file)
@@ -1,3 +1,52 @@
+2005-04-06  Corinna Vinschen  <corinna@vinschen.de>
+
+       * bsd_helper.cc (ipcexit_hookthread): Fix whitespace and handle leak.
+       * bsd_mutex.cc: Include stdlib.h, sys/msg.h and sys/sem.h.
+       (mtx_init): Initialize lock counter to 0.
+       (_mtx_lock): Increment and log mutex lock counter.
+       (mtx_owned): Add winpid argument. Return true only if mutex is
+       actually owned by process winpid.
+       (_mtx_assert): Add winpid argument accordingly.
+       (_mtx_unlock): Log owner and lock count.
+       (MSLEEP_MUTEX): Remove.
+       (MSLEEP_SEM): Ditto.
+       (MSLEEP_EVENT): Ditto.
+       (msleep_event_name): Ditto.
+       (msleep_cs): New global critical section.
+       (msleep_cnt): New global variable indicating msleep record usage.
+       (msleep_max_cnt): New global variable indicating msleep record size.
+       (msleep_arr): New global pointer to msleep records.
+       (msleep_init): Initialize msleep_cs. Allocate msleep_arr array.
+       (_msleep): Rewrite using new msleep_cs/msleep_arr based thread
+       synchronization. Don't be shy with debug output.
+       (wakeup): Rewrite using new msleep_cs/msleep_arr based thread
+       synchronization.
+       * bsd_mutex.h (struct mtx): Add lock counter for better debugging.
+       (mtx_owned): Declare with winpid argument.
+       (_mtx_assert): Ditto.
+       (mtx_assert): Define with winpid argument.
+       * cygserver.cc (version): Remove.
+       (SERVER_VERSION): New define, decoupling server version information
+       from source code control system.
+       (print_version): Simplify printing server version.
+       * process.cc (process::process): Fix wrong bracketing (and handle leak).
+       (process::~process): Only try to close _signal_arrived if valid.
+       * sysv_sem.cc: Include sys/smallprint.h.
+       (semundo_clear): Define with additional struct thread pointer argument.
+       Accomodate throughout.
+       (SEMUNDO_LOCKASSERT): Define with winpid argument. Accomodate
+       throughout.
+       (struct sem_undo): Define un_proc as pid_t on Cygwin. Accomodate
+       throughout.
+       (seminit): Improve debugging by adding the semid to the mutex name.
+       (semget): Correctly print key value as 64 bit hex value in debug
+       output.
+       (semexit_myhook): Remove Cygwin specific unlocking of mutexes owned
+       by exiting process.  Keep semaphore global lock throughout whole
+       function to avoid races.
+       * sysv_shm.cc (GIANT_REQUIRED): Define empty on Cygwin. We know that
+       Giant is locked.
+
 2005-04-01  Corinna Vinschen  <corinna@vinschen.de>
 
        * bsd_mutex.cc (_msleep): Whitespace fix.
index 364dddd7f59bdc0cbdc942a18a5b6dfafd883c04..9fb3c9bfadd3c215b5f732b46e8ff1d23e743219 100644 (file)
@@ -1,6 +1,6 @@
 /* bsd_helper.cc
 
-   Copyright 2003, 2004 Red Hat Inc.
+   Copyright 2003, 2004, 2005 Red Hat Inc.
 
 This file is part of Cygwin.
 
@@ -129,7 +129,7 @@ ipcexit_hookthread (const LPVOID param)
           exiting process and shmexit_myhook to keep track of shared
           memory. */
        if (Giant.owner == shs->ipcblk.winpid)
-               mtx_unlock (&Giant);
+         mtx_unlock (&Giant);
        if (support_semaphores == TUN_TRUE)
          semexit_myhook (NULL, &shs->ipcblk);
        if (support_sharedmem == TUN_TRUE)
@@ -152,6 +152,7 @@ ipcexit_hookthread (const LPVOID param)
       if (ipcht_entry->winpid == shs->ipcblk.winpid)
         {
          SLIST_REMOVE (&ipcht_list, ipcht_entry, ipc_hookthread, sht_next);
+         CloseHandle (ipcht_entry->thread);
          delete ipcht_entry;
        }
     }
index 82ce4bf27c09c979477b789079e6d3a24ff76ebf..a470b26d5016d5437675767eb9045efe3f3fcee1 100644 (file)
@@ -14,6 +14,9 @@ details. */
 #define __BSD_VISIBLE 1
 #include <sys/smallprint.h>
 #include <limits.h>
+#include <stdlib.h>
+#include <sys/msg.h>
+#include <sys/sem.h>
 
 #include "process.h"
 #include "cygserver_ipc.h"
@@ -26,6 +29,7 @@ mtx_init (mtx *m, const char *name, const void *, int)
 {
   m->name = name;
   m->owner = 0;
+  m->cnt = 0;
   /* Can't use Windows Mutexes here since Windows Mutexes are only
      unlockable by the lock owner. */
   m->h = CreateSemaphore (NULL, 1, 1, NULL);
@@ -36,30 +40,32 @@ mtx_init (mtx *m, const char *name, const void *, int)
 void
 _mtx_lock (mtx *m, DWORD winpid, const char *file, int line)
 {
-  _log (file, line, LOG_DEBUG, "Try locking mutex %s", m->name);
+  _log (file, line, LOG_DEBUG, "Try locking mutex %s (%u) (hold: %u)",
+       m->name, winpid, m->owner);
   if (WaitForSingleObject (m->h, INFINITE) != WAIT_OBJECT_0)
     _panic (file, line, "wait for %s in %d failed, %E", m->name, winpid);
   m->owner = winpid;
-  _log (file, line, LOG_DEBUG, "Locked      mutex %s", m->name);
+  _log (file, line, LOG_DEBUG, "Locked      mutex %s/%u (%u)",
+       m->name, ++m->cnt, winpid);
 }
 
 int
-mtx_owned (mtx *m)
+mtx_owned (mtx *m, DWORD winpid)
 {
-  return m->owner > 0;
+  return m->owner == winpid;
 }
 
 void
-_mtx_assert (mtx *m, int what, const char *file, int line)
+_mtx_assert (mtx *m, int what, DWORD winpid, const char *file, int line)
 {
   switch (what)
     {
       case MA_OWNED:
-        if (!mtx_owned (m))
+        if (!mtx_owned (m, winpid))
          _panic (file, line, "Mutex %s not owned", m->name);
        break;
       case MA_NOTOWNED:
-        if (mtx_owned (m))
+        if (mtx_owned (m, winpid))
          _panic (file, line, "Mutex %s is owned", m->name);
         break;
       default:
@@ -70,6 +76,8 @@ _mtx_assert (mtx *m, int what, const char *file, int line)
 void
 _mtx_unlock (mtx *m, const char *file, int line)
 {
+  DWORD owner = m->owner;
+  unsigned long cnt = m->cnt;
   m->owner = 0;
   /* Cautiously check if mtx_destroy has been called (shutdown).
      In that case, m->h is NULL. */
@@ -82,7 +90,8 @@ _mtx_unlock (mtx *m, const char *file, int line)
           || (wincap.is_winnt () && GetLastError () != ERROR_TOO_MANY_POSTS))
        _panic (file, line, "release of mutex %s failed, %E", m->name);
     }
-  _log (file, line, LOG_DEBUG, "Unlocked    mutex %s", m->name);
+  _log (file, line, LOG_DEBUG, "Unlocked    mutex %s/%u (owner: %u)",
+       m->name, cnt, owner);
 }
 
 void
@@ -98,22 +107,6 @@ mtx_destroy (mtx *m)
  * Helper functions for msleep/wakeup.
  */
 
-/* Values for which */
-#define MSLEEP_MUTEX   0
-#define MSLEEP_SEM     1
-#define MSLEEP_EVENT   2
-
-static char *
-msleep_event_name (void *ident, char *name, int which)
-{
-  if (wincap.has_terminal_services ())
-    __small_sprintf (name, "Global\\cygserver.msleep.evt.%1d.%08x",
-                    which, ident);
-  else
-    __small_sprintf (name, "cygserver.msleep.evt.%1d.%08x", which, ident);
-  return name;
-}
-
 static int
 win_priority (int priority)
 {
@@ -172,13 +165,36 @@ set_priority (int priority)
  * flag the mutex is not entered before returning.
  */
 static HANDLE msleep_glob_evt;
+CRITICAL_SECTION msleep_cs;
+static long msleep_cnt;
+static long msleep_max_cnt;
+static struct msleep_record {
+  void *ident;
+  HANDLE wakeup_evt;
+  LONG threads;
+} *msleep_arr;
 
 void
 msleep_init (void)
 {
+  extern struct msginfo msginfo;
+  extern struct seminfo seminfo;
+
   msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
   if (!msleep_glob_evt)
     panic ("CreateEvent in msleep_init failed: %E");
+  InitializeCriticalSection (&msleep_cs);
+  long msgmni = support_msgqueues ? msginfo.msgmni : 0;
+  long semmni = support_semaphores ? seminfo.semmni : 0;
+  TUNABLE_INT_FETCH ("kern.ipc.msgmni", &msgmni);
+  TUNABLE_INT_FETCH ("kern.ipc.semmni", &semmni);
+  debug ("Try allocating msgmni (%d) + semmni (%d) msleep records",
+        msgmni, semmni);
+  msleep_max_cnt = msgmni + semmni;
+  msleep_arr = (struct msleep_record *) calloc (msleep_max_cnt,
+                                               sizeof (struct msleep_record));
+  if (!msleep_arr)
+    panic ("Allocating msleep records in msleep_init failed: %d", errno);
 }
 
 int
@@ -186,46 +202,47 @@ _msleep (void *ident, struct mtx *mtx, int priority,
        const char *wmesg, int timo, struct thread *td)
 {
   int ret = -1;
-  char name[64];
-
-  /* The mutex is used to indicate an ident specific critical section.
-     The critical section is needed to synchronize access to the
-     semaphore and eventually the event object.  The whole idea is
-     that a wakeup is *guaranteed* to wakeup *all* threads.  If that's
-     not synchronized, sleeping threads could return into the msleep
-     function before all other threads have called CloseHandle(evt).
-     That's bad, since the event still exists and is signalled! */
-  HANDLE mutex = CreateMutex (NULL, FALSE,
-                             msleep_event_name (ident, name, MSLEEP_MUTEX));
-  if (!mutex)
-    panic ("CreateMutex in msleep (%s) failed: %E", wmesg);
-  WaitForSingleObject (mutex, INFINITE);
+  int i;
 
-  /* Ok, we're in the critical section now.  We create an ident specific
-     semaphore, which is used to synchronize the waiting threads. */
-  HANDLE sem = CreateSemaphore (NULL, 0, LONG_MAX,
-                               msleep_event_name (ident, name, MSLEEP_SEM));
-  if (!sem)
-    panic ("CreateSemaphore in msleep (%s) failed: %E", wmesg);
-
-  /* This thread is one more thread sleeping.  The semaphore value is
-     so used as a counter of sleeping threads.  That info is needed by
-     the wakeup function. */
-  ReleaseSemaphore (sem, 1, NULL);
-
-  /* Leave critical section. */
-  ReleaseMutex (mutex);
+  while (1)
+    {
+      EnterCriticalSection (&msleep_cs);
+      for (i = 0; i < msleep_cnt; ++i)
+       if (msleep_arr[i].ident == ident)
+         break;
+      if (!msleep_arr[i].ident)
+       {
+         debug ("New ident %x, index %d", ident, i);
+         if (i >= msleep_max_cnt)
+           panic ("Too many idents to wait for.\n");
+         msleep_arr[i].ident = ident;
+         msleep_arr[i].wakeup_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
+         if (!msleep_arr[i].wakeup_evt)
+           panic ("CreateEvent in msleep (%s) failed: %E", wmesg);
+         msleep_arr[i].threads = 1;
+         ++msleep_cnt;
+         LeaveCriticalSection (&msleep_cs);
+         break;
+       }
+      else if (WaitForSingleObject (msleep_arr[i].wakeup_evt, 0)
+              != WAIT_OBJECT_0)
+       {
+         ++msleep_arr[i].threads;
+         LeaveCriticalSection (&msleep_cs);
+         break;
+       }
+      /* Otherwise wakeup has been called, so sleep to wait until all
+         formerly waiting threads have left and retry. */
+      LeaveCriticalSection (&msleep_cs);
+      Sleep (1L);
+    }
 
-  HANDLE evt = CreateEvent (NULL, TRUE, FALSE,
-                           msleep_event_name (ident, name, MSLEEP_EVENT));
-  if (!evt)
-    panic ("CreateEvent in msleep (%s) failed: %E", wmesg);
   if (mtx)
     mtx_unlock (mtx);
   int old_priority = set_priority (priority);
   HANDLE obj[4] =
     {
-      evt,
+      msleep_arr[i].wakeup_evt,
       msleep_glob_evt,
       td->client->handle (),
       td->client->signal_arrived ()
@@ -241,37 +258,45 @@ _msleep (void *ident, struct mtx *mtx, int priority,
     {
       case WAIT_OBJECT_0:      /* wakeup() has been called. */
        ret = 0;
+       debug ("msleep wakeup called");
         break;
       case WAIT_OBJECT_0 + 1:  /* Shutdown event (triggered by wakeup_all). */
         priority |= PDROP;
        /*FALLTHRU*/
       case WAIT_OBJECT_0 + 2:  /* The dependent process has exited. */
+       debug ("msleep process exit or shutdown");
        ret = EIDRM;
         break;
       case WAIT_OBJECT_0 + 3:  /* Signal for calling process arrived. */
+       debug ("msleep process got signal");
         ret = EINTR;
        break;
       case WAIT_TIMEOUT:
         ret = EWOULDBLOCK;
         break;
       default:
-       panic ("wait in msleep (%s) failed, %E", wmesg);
+       /* There's a chance that a process has been terminated before
+          WaitForMultipleObjects has been called.  In this case the handles
+          might be invalid.  The error code returned is ERROR_INVALID_HANDLE.
+          Since we can trust the values of these handles otherwise, we
+          treat an ERROR_INVALID_HANDLE as a normal process termination and
+          hope for the best. */
+       if (GetLastError () != ERROR_INVALID_HANDLE)
+         panic ("wait in msleep (%s) failed, %E", wmesg);
+       ret = EIDRM;
        break;
     }
 
-  CloseHandle (evt);
-  /* wakeup has reset the semaphore to 0.  Now indicate that this thread
-     has called CloseHandle (evt) and enter the critical section.  The
-     critical section is still hold by wakeup, until all formerly sleeping
-     threads have indicated that the event has been dismissed.  That's
-     the signal for wakeup that it's the only thread still holding a
-     handle to the event object.  wakeup will then close the last handle
-     and leave the critical section. */
-  ReleaseSemaphore (sem, 1, NULL);
-  WaitForSingleObject (mutex, INFINITE);
-  CloseHandle (sem);
-  ReleaseMutex (mutex);
-  CloseHandle (mutex);
+  EnterCriticalSection (&msleep_cs);
+  if (--msleep_arr[i].threads == 0)
+    {
+      CloseHandle (msleep_arr[i].wakeup_evt);
+      msleep_arr[i].ident = NULL;
+      --msleep_cnt;
+      if (i < msleep_cnt)
+        msleep_arr[i] = msleep_arr[msleep_cnt];
+    }
+  LeaveCriticalSection (&msleep_cs);
 
   set_priority (old_priority);
 
@@ -286,70 +311,15 @@ _msleep (void *ident, struct mtx *mtx, int priority,
 int
 wakeup (void *ident)
 {
-  char name[64];
-  LONG threads;
-
-  HANDLE evt = OpenEvent (EVENT_MODIFY_STATE, FALSE,
-                         msleep_event_name (ident, name, MSLEEP_EVENT));
-  if (!evt) /* No thread is waiting. */
-    {
-      /* Another round of different error codes returned by 9x and NT
-         systems. Oh boy... */
-      if (  (!wincap.is_winnt () && GetLastError () != ERROR_INVALID_NAME)
-         || (wincap.is_winnt () && GetLastError () != ERROR_FILE_NOT_FOUND))
-       panic ("OpenEvent (%s) in wakeup failed: %E", name);
-      return 0;
-    }
-
-  /* The mutex is used to indicate an ident specific critical section.
-     The critical section is needed to synchronize access to the
-     semaphore and eventually the event object.  The whole idea is
-     that a wakeup is *guaranteed* to wakeup *all* threads.  If that's
-     not synchronized, sleeping threads could return into the msleep
-     function before all other threads have called CloseHandle(evt).
-     That's bad, since the event still exists and is signalled! */
-  HANDLE mutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE,
-                           msleep_event_name (ident, name, MSLEEP_MUTEX));
-  if (!mutex)
-    panic ("OpenMutex (%s) in wakeup failed: %E", name);
-  WaitForSingleObject (mutex, INFINITE);
-  /* Ok, we're in the critical section now.  We create an ident specific
-     semaphore, which is used to synchronize the waiting threads. */
-  HANDLE sem = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE,
-                             msleep_event_name (ident, name, MSLEEP_SEM));
-  if (!sem)
-    panic ("OpenSemaphore (%s) in wakeup failed: %E", name);
-  ReleaseSemaphore (sem, 1, &threads);
-  /* `threads' is the number of waiting threads.  Now reset the semaphore
-     to 0 and wait for this number of threads to indicate that they have
-     called CloseHandle (evt).  Then it's save to do the same here in
-     wakeup, which then means that the event object is destroyed and
-     can get safely recycled. */
-  for (int i = threads + 1; i > 0; --i)
-    WaitForSingleObject (sem, INFINITE);
-
-  if (!SetEvent (evt))
-    panic ("SetEvent (%s) in wakeup failed, %E", name);
-
-  /* Now wait for all threads which were waiting for this wakeup. */
-  while (threads-- > 0)
-    WaitForSingleObject (sem, INFINITE);
-
-  /* Now our handle is the last handle to this event object. */
-  CloseHandle (evt);
-  /* But paranoia rulez, so we check here again. */
-  evt = OpenEvent (EVENT_MODIFY_STATE, FALSE,
-                  msleep_event_name (ident, name, MSLEEP_EVENT));
-  if (evt)
-    panic ("Event %s has not been destroyed.  Obviously I can't count :-(",
-          name);
-
-  CloseHandle (sem);
-
-  /* Leave critical section (all of wakeup is critical). */
-  ReleaseMutex (mutex);
-  CloseHandle (mutex);
-
+  int i;
+
+  EnterCriticalSection (&msleep_cs);
+  for (i = 0; i < msleep_cnt; ++i)
+    if (msleep_arr[i].ident == ident)
+      break;
+  if (msleep_arr[i].ident)
+    SetEvent (msleep_arr[i].wakeup_evt);
+  LeaveCriticalSection (&msleep_cs);
   return 0;
 }
 
index 3b07bf3c61fdfcdfcc2a8fba9e420b8bd5deca9c..c9f5015766bc53b35f4bd0f0ac9a42a234a400a5 100644 (file)
@@ -1,6 +1,6 @@
 /* bsd_mutex.h: BSD Mutex helper
 
-   Copyright 2003 Red Hat, Inc.
+   Copyright 2003, 2005 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -25,6 +25,7 @@ struct mtx {
   HANDLE h;
   const char *name;
   DWORD owner;
+  unsigned long cnt;
 };
 
 /* Some BSD kernel global mutex. */
@@ -33,9 +34,9 @@ extern struct mtx Giant;
 void mtx_init (mtx *, const char *, const void *, int);
 void _mtx_lock (mtx *, DWORD winpid, const char *, int);
 #define mtx_lock(m) _mtx_lock((m), (td->ipcblk->winpid), __FILE__, __LINE__)
-int mtx_owned (mtx *);
-void _mtx_assert(mtx *, int, const char *, int);
-#define mtx_assert(m,w) _mtx_assert((m),(w),__FILE__,__LINE__)
+int mtx_owned (mtx *, DWORD);
+void _mtx_assert(mtx *, int, DWORD winpid, const char *, int);
+#define mtx_assert(m,w,p) _mtx_assert((m),(w),(p),__FILE__,__LINE__)
 void _mtx_unlock (mtx *, const char *, int);
 #define mtx_unlock(m) _mtx_unlock((m),__FILE__,__LINE__)
 
index 88f5e67a819fb0ade04a3af8270f7049a675decf..5cf82f38e178395a5a447333f3663d0888e8e7b4 100644 (file)
@@ -1,6 +1,6 @@
 /* cygserver.cc
 
-   Copyright 2001, 2002, 2003, 2004 Red Hat Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005 Red Hat Inc.
 
    Written by Egor Duda <deo@logos-m.ru>
 
@@ -37,8 +37,7 @@ details. */
 
 #define DEF_CONFIG_FILE        "" SYSCONFDIR "/cygserver.conf"
 
-// Version string.
-static const char version[] = "$Revision$";
+#define SERVER_VERSION "1.12"
 
 GENERIC_MAPPING access_mapping;
 
@@ -496,24 +495,6 @@ print_usage (const char *const pgm)
 static void
 print_version ()
 {
-  char *vn = NULL;
-
-  const char *const colon = strchr (version, ':');
-
-  if (!colon)
-    {
-      vn = strdup ("?");
-    }
-  else
-    {
-      vn = strdup (colon + 2); // Skip ": "
-
-      char *const spc = strchr (vn, ' ');
-
-      if (spc)
-       *spc = '\0';
-    }
-
   char buf[200];
   snprintf (buf, sizeof (buf), "%d.%d.%d(%d.%d/%d/%d)-(%d.%d.%d.%d) %s",
            cygwin_version.dll_major / 1000,
@@ -531,12 +512,10 @@ print_version ()
 
   log (LOG_INFO, "(cygwin) %s\n"
                  "API version %s\n"
-                 "Copyright 2001, 2002, 2003 Red Hat, Inc.\n"
+                 "Copyright 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.\n"
                  "Compiled on %s\n"
                  "Default configuration file is %s",
-                 vn, buf, __DATE__, DEF_CONFIG_FILE);
-
-  free (vn);
+                 SERVER_VERSION, buf, __DATE__, DEF_CONFIG_FILE);
 }
 
 /*
index 6f8f40ea5c485300f830f4433328cf9a2601f4ea..eb7e0940d8f0c897237fec199311ef4f51b4d473 100644 (file)
@@ -68,9 +68,11 @@ process::process (const pid_t cygpid, const DWORD winpid, HANDLE signal_arrived)
       if (!DuplicateHandle (_hProcess, signal_arrived,
                            GetCurrentProcess (), &_signal_arrived,
                            0, FALSE, DUPLICATE_SAME_ACCESS))
-       system_printf ("error getting signal_arrived to server (%lu)",
-                      GetLastError ());
-       _signal_arrived = INVALID_HANDLE_VALUE;
+       {
+         system_printf ("error getting signal_arrived to server (%lu)",
+                        GetLastError ());
+         _signal_arrived = INVALID_HANDLE_VALUE;
+       }
     }
   InitializeCriticalSection (&_access);
   debug ("initialized (%lu)", _cygpid);
@@ -80,7 +82,8 @@ process::~process ()
 {
   debug ("deleting (%lu)", _cygpid);
   DeleteCriticalSection (&_access);
-  CloseHandle (_signal_arrived);
+  if (_signal_arrived && _signal_arrived != INVALID_HANDLE_VALUE)
+    CloseHandle (_signal_arrived);
   CloseHandle (_hProcess);
 }
 
index bcd0dc251a8fba902cc511e0580932f09ca83f4e..477df4a261eb4d8352f79851d0b99f543411ce5f 100644 (file)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_sem.c,v 1.70 2004/05/30 20
 #include "cygserver.h"
 #include "process.h"
 #include "cygserver_ipc.h"
+#include <sys/smallprint.h>
 
 #ifdef __CYGWIN__
 #define __semctl semctl
@@ -53,7 +54,7 @@ static int semvalid(int semid, struct semid_ds *semaptr);
 static struct sem_undo *semu_alloc(struct thread *td);
 static int semundo_adjust(struct thread *td, struct sem_undo **supptr,
                int semid, int semnum, int adjval);
-static void semundo_clear(int semid, int semnum);
+static void semundo_clear(int semid, int semnum, struct thread *td);
 
 #ifndef _SYS_SYSPROTO_H_
 struct __semctl_args;
@@ -88,7 +89,7 @@ static eventhandler_tag semexit_tag;
 #define SEMUNDO_LOCK()         mtx_lock(&SEMUNDO_MTX);
 #define SEMUNDO_HOOKLOCK()     _mtx_lock(&SEMUNDO_MTX, p->winpid, __FILE__, __LINE__);
 #define SEMUNDO_UNLOCK()       mtx_unlock(&SEMUNDO_MTX);
-#define SEMUNDO_LOCKASSERT(how)        mtx_assert(&SEMUNDO_MTX, (how));
+#define SEMUNDO_LOCKASSERT(how,pid)    mtx_assert(&SEMUNDO_MTX, (how), (pid));
 
 struct sem {
        u_short semval;         /* semaphore value */
@@ -108,7 +109,11 @@ struct undo {
 
 struct sem_undo {
        SLIST_ENTRY(sem_undo) un_next;  /* ptr to next active undo structure */
+#ifdef __CYGWIN__
+       DWORD   un_proc;                /* owner of this structure */
+#else
        struct  proc *un_proc;          /* owner of this structure */
+#endif
        short   un_cnt;                 /* # of active entries */
        struct undo un_ent[1];          /* undo entries */
 };
@@ -240,10 +245,18 @@ seminit(void)
                sema[i].sem_perm.seq = 0;
        }
        for (i = 0; i < seminfo.semmni; i++)
-               mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF);
+       {
+          char *buf = (char *)malloc (16);
+          __small_sprintf (buf, "semid[%d]", i);
+               mtx_init(&sema_mtx[i], buf, NULL, MTX_DEF);
+       }
        for (i = 0; i < seminfo.semmnu; i++) {
                struct sem_undo *suptr = SEMU(i);
+#ifdef __CYGWIN__
+               suptr->un_proc = 0;
+#else
                suptr->un_proc = NULL;
+#endif
        }
        SLIST_INIT(&semu_list);
        mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
@@ -351,7 +364,7 @@ semu_alloc(struct thread *td)
        struct sem_undo **supptr;
        int attempt;
 
-       SEMUNDO_LOCKASSERT(MA_OWNED);
+       SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
        /*
         * Try twice to allocate something.
         * (we'll purge an empty structure after the first pass so
@@ -366,10 +379,14 @@ semu_alloc(struct thread *td)
 
                for (i = 0; i < seminfo.semmnu; i++) {
                        suptr = SEMU(i);
+#ifdef __CYGWIN__
+                       if (suptr->un_proc == 0) {
+#else
                        if (suptr->un_proc == NULL) {
+#endif
                                SLIST_INSERT_HEAD(&semu_list, suptr, un_next);
                                suptr->un_cnt = 0;
-                               suptr->un_proc = td->td_proc;
+                               suptr->un_proc = td->td_proc->winpid;
                                return(suptr);
                        }
                }
@@ -386,7 +403,11 @@ semu_alloc(struct thread *td)
                        SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list,
                            un_next) {
                                if (suptr->un_cnt == 0) {
+#ifdef __CYGWIN__
+                                       suptr->un_proc = 0;
+#else
                                        suptr->un_proc = NULL;
+#endif
                                        did_something = 1;
                                        *supptr = SLIST_NEXT(suptr, un_next);
                                        break;
@@ -421,7 +442,7 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
        struct undo *sunptr;
        int i;
 
-       SEMUNDO_LOCKASSERT(MA_OWNED);
+       SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
        /* Look for and remember the sem_undo if the caller doesn't provide
           it */
 
@@ -429,7 +450,7 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
        if (suptr == NULL) {
                SLIST_FOREACH(suptr, &semu_list, un_next) {
 #ifdef __CYGWIN__
-                       if (suptr->un_proc->cygpid == p->cygpid) {
+                       if (suptr->un_proc == p->winpid) {
 #else
                        if (suptr->un_proc == p) {
 #endif
@@ -486,11 +507,11 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
 }
 
 static void
-semundo_clear(int semid, int semnum)
+semundo_clear(int semid, int semnum, struct thread *td)
 {
        struct sem_undo *suptr;
 
-       SEMUNDO_LOCKASSERT(MA_OWNED);
+       SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
        SLIST_FOREACH(suptr, &semu_list, un_next) {
                struct undo *sunptr = &suptr->un_ent[0];
                int i = 0;
@@ -647,7 +668,7 @@ __semctl(struct thread *td, struct __semctl_args *uap)
                }
                semaptr->sem_perm.mode = 0;
                SEMUNDO_LOCK();
-               semundo_clear(semid, -1);
+               semundo_clear(semid, -1, td);
                SEMUNDO_UNLOCK();
                wakeup(semaptr);
                break;
@@ -770,7 +791,7 @@ __semctl(struct thread *td, struct __semctl_args *uap)
                }
                semaptr->sem_base[semnum].semval = real_arg.val;
                SEMUNDO_LOCK();
-               semundo_clear(semid, semnum);
+               semundo_clear(semid, semnum, td);
                SEMUNDO_UNLOCK();
                wakeup(semaptr);
                break;
@@ -808,7 +829,7 @@ raced:
                        semaptr->sem_base[i].semval = usval;
                }
                SEMUNDO_LOCK();
-               semundo_clear(semid, -1);
+               semundo_clear(semid, -1, td);
                SEMUNDO_UNLOCK();
                wakeup(semaptr);
                break;
@@ -821,7 +842,7 @@ raced:
        if (error == 0)
                td->td_retval[0] = rval;
 done2:
-       if (mtx_owned(sema_mtxp))
+       if (mtx_owned(sema_mtxp, td->td_proc->winpid))
                mtx_unlock(sema_mtxp);
        if (array != NULL)
                sys_free(array, M_TEMP);
@@ -850,7 +871,7 @@ semget(struct thread *td, struct semget_args *uap)
        struct ucred *cred = td->td_ucred;
 #endif
 
-       DPRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg));
+       DPRINTF(("semget(0x%X, %d, 0%o)\n", key, nsems, semflg));
        if (!jail_sysvipc_allowed && jailed(td->td_ucred))
                return (ENOSYS);
 
@@ -1056,7 +1077,7 @@ semop(struct thread *td, struct semop_args *uap)
                        semptr = &semaptr->sem_base[sopptr->sem_num];
 
                        DPRINTF((
-                           "semop:  semaptr=%x, sem_base=%x, "
+                           "semop: semaptr=%x, sem_base=%x, "
                            "semptr=%x, sem[%d]=%d : op=%d, flag=%s\n",
                            semaptr, semaptr->sem_base, semptr,
                            sopptr->sem_num, semptr->semval, sopptr->sem_op,
@@ -1252,18 +1273,6 @@ semexit_myhook(void *arg, struct proc *p)
        struct sem_undo *suptr;
        struct sem_undo **supptr;
 
-#ifdef __CYGWIN__
-       /*
-        * Search all mutexes, if some of them are still owned by the
-        * leaving process.  If so, unlock them.
-        */
-       if (sem_mtx.owner == p->winpid)
-               mtx_unlock(&sem_mtx);
-       for (int i = 0; i < seminfo.semmni; i++)
-               if (sema_mtx[i].owner == p->winpid)
-                       mtx_unlock(&sema_mtx[i]);
-#endif /* __CYGWIN__ */
-
        /*
         * Go through the chain of undo vectors looking for one
         * associated with this process.
@@ -1271,16 +1280,20 @@ semexit_myhook(void *arg, struct proc *p)
        SEMUNDO_HOOKLOCK();
        SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, un_next) {
 #ifdef __CYGWIN__
-               if (suptr->un_proc->cygpid == p->cygpid)
+               if (suptr->un_proc == p->winpid)
 #else
                if (suptr->un_proc == p)
 #endif
                        break;
        }
+#ifndef __CYGWIN__
        SEMUNDO_UNLOCK();
+#endif
 
-       if (suptr == NULL)
+       if (suptr == NULL) {
+               SEMUNDO_UNLOCK();
                return;
+       }
 
 #ifdef __CYGWIN__
        DPRINTF(("proc @%u(%u) has undo structure with %d entries\n",
@@ -1309,8 +1322,8 @@ semexit_myhook(void *arg, struct proc *p)
                        _mtx_lock(sema_mtxp, p->winpid, __FILE__, __LINE__);
 #else
                        mtx_lock(sema_mtxp);
-#endif
                        SEMUNDO_HOOKLOCK();
+#endif
                        if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
                                panic("semexit - semid not allocated");
                        if (semnum >= semaptr->sem_nsems)
@@ -1318,13 +1331,11 @@ semexit_myhook(void *arg, struct proc *p)
 
                        DPRINTF((
 #ifdef __CYGWIN__
-                           "semexit:  %u(%u) id=%d num=%d(adj=%d) ; sem=%d\n",
-                           suptr->un_proc->cygpid, suptr->un_proc->winpid,
-                           suptr->un_ent[ix].un_id,
+                           "semexit:  %u id=%d num=%d(adj=%d) ; sem=%d\n",
 #else
                            "semexit:  %08x id=%d num=%d(adj=%d) ; sem=%d\n",
-                           suptr->un_proc, suptr->un_ent[ix].un_id,
 #endif
+                           suptr->un_proc, suptr->un_ent[ix].un_id,
                            suptr->un_ent[ix].un_num,
                            suptr->un_ent[ix].un_adjval,
                            semaptr->sem_base[semnum].semval));
@@ -1340,17 +1351,26 @@ semexit_myhook(void *arg, struct proc *p)
 
                        wakeup(semaptr);
                        DPRINTF(("semexit:  back from wakeup\n"));
-                       mtx_unlock(sema_mtxp);
+                       _mtx_unlock(sema_mtxp, __FILE__, __LINE__);
+#ifndef __CYGWIN__
                        SEMUNDO_UNLOCK();
+#endif
                }
        }
 
        /*
         * Deallocate the undo vector.
         */
-       DPRINTF(("removing vector\n"));
+       DPRINTF(("removing vector (%u)\n", suptr->un_proc));
+#ifdef __CYGWIN__
+       suptr->un_proc = 0;
+#else
        suptr->un_proc = NULL;
+#endif
        *supptr = SLIST_NEXT(suptr, un_next);
+#ifdef __CYGWIN__
+       SEMUNDO_UNLOCK();
+#endif
 }
 
 #ifndef __CYGWIN__
index dc77103f56eeefe3d36176e6564b59e5ec13fe6d..2b675875592c258375049bdcd5b78590a3ed7778 100644 (file)
@@ -68,7 +68,11 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_shm.c,v 1.89 2003/11/07 04
 #define btoc(b)        (((b) + PAGE_MASK) / PAGE_SIZE)
 #define round_page(p) ((((unsigned long)(p)) + PAGE_MASK) & ~(PAGE_MASK))
 #define ACCESSPERMS (0777)
+#ifdef __CYGWIN__
+#define GIANT_REQUIRED
+#else
 #define GIANT_REQUIRED mtx_assert(&Giant, MA_OWNED)
+#endif
 #define KERN_SUCCESS 0
 #define VM_PROT_READ   PROT_READ
 #define VM_PROT_WRITE  PROT_WRITE
This page took 0.059873 seconds and 5 git commands to generate.