Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygserver/bsd_mutex.cc')
-rw-r--r--winsup/cygserver/bsd_mutex.cc365
1 files changed, 0 insertions, 365 deletions
diff --git a/winsup/cygserver/bsd_mutex.cc b/winsup/cygserver/bsd_mutex.cc
deleted file mode 100644
index 27217486a..000000000
--- a/winsup/cygserver/bsd_mutex.cc
+++ /dev/null
@@ -1,365 +0,0 @@
-/* bsd_mutex.cc
-
- Copyright 2003, 2004 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. */
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-#include <errno.h>
-#define _KERNEL 1
-#define __BSD_VISIBLE 1
-#include <sys/smallprint.h>
-#include <limits.h>
-
-#include "process.h"
-#include "cygserver_ipc.h"
-
-/* A BSD kernel global mutex. */
-struct mtx Giant;
-
-void
-mtx_init (mtx *m, const char *name, const void *, int)
-{
- m->name = name;
- m->owner = 0;
- /* Can't use Windows Mutexes here since Windows Mutexes are only
- unlockable by the lock owner. */
- m->h = CreateSemaphore (NULL, 1, 1, NULL);
- if (!m->h)
- panic ("couldn't allocate %s mutex, %E\n", name);
-}
-
-void
-_mtx_lock (mtx *m, DWORD winpid, const char *file, int line)
-{
- _log (file, line, LOG_DEBUG, "Try locking mutex %s", m->name);
- 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);
-}
-
-int
-mtx_owned (mtx *m)
-{
- return m->owner > 0;
-}
-
-void
-_mtx_assert (mtx *m, int what, const char *file, int line)
-{
- switch (what)
- {
- case MA_OWNED:
- if (!mtx_owned (m))
- _panic (file, line, "Mutex %s not owned", m->name);
- break;
- case MA_NOTOWNED:
- if (mtx_owned (m))
- _panic (file, line, "Mutex %s is owned", m->name);
- break;
- default:
- break;
- }
-}
-
-void
-_mtx_unlock (mtx *m, const char *file, int line)
-{
- m->owner = 0;
- /* Cautiously check if mtx_destroy has been called (shutdown).
- In that case, m->h is NULL. */
- if (m->h && !ReleaseSemaphore (m->h, 1, NULL))
- {
- /* Check if the semaphore was already on it's max value. In this case,
- ReleaseSemaphore returns FALSE with an error code which *sic* depends
- on the OS. */
- if ( (!wincap.is_winnt () && GetLastError () != ERROR_INVALID_PARAMETER)
- || (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);
-}
-
-void
-mtx_destroy (mtx *m)
-{
- HANDLE tmp = m->h;
- m->h = NULL;
- if (tmp)
- CloseHandle (tmp);
-}
-
-/*
- * 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)
-{
- int p = (int)((priority) & PRIO_MASK) - PZERO;
- /* Generating a valid priority value is a bit tricky. The only valid
- values on 9x and NT4 are -15, -2, -1, 0, 1, 2, 15. */
- switch (p)
- {
- case -15: case -14: case -13: case -12: case -11:
- return THREAD_PRIORITY_IDLE;
- case -10: case -9: case -8: case -7: case -6:
- return THREAD_PRIORITY_LOWEST;
- case -5: case -4: case -3: case -2: case -1:
- return THREAD_PRIORITY_BELOW_NORMAL;
- case 0:
- return THREAD_PRIORITY_NORMAL;
- case 1: case 2: case 3: case 4: case 5:
- return THREAD_PRIORITY_ABOVE_NORMAL;
- case 6: case 7: case 8: case 9: case 10:
- return THREAD_PRIORITY_HIGHEST;
- case 11: case 12: case 13: case 14: case 15:
- return THREAD_PRIORITY_TIME_CRITICAL;
- }
- return THREAD_PRIORITY_NORMAL;
-}
-
-/*
- * Sets the thread priority, returns the old priority.
- */
-static int
-set_priority (int priority)
-{
- int old_prio = GetThreadPriority (GetCurrentThread ());
- if (!SetThreadPriority (GetCurrentThread (), win_priority (priority)))
- log (LOG_WARNING,
- "Warning: Setting thread priority to %d failed with error %lu\n",
- win_priority (priority), GetLastError ());
- return old_prio;
-}
-
-/*
- * Original description from BSD code:
- *
- * General sleep call. Suspends the current process until a wakeup is
- * performed on the specified identifier. The process will then be made
- * runnable with the specified priority. Sleeps at most timo/hz seconds
- * (0 means no timeout). If pri includes PCATCH flag, signals are checked
- * before and after sleeping, else signals are not checked. Returns 0 if
- * awakened, EWOULDBLOCK if the timeout expires. If PCATCH is set and a
- * signal needs to be delivered, ERESTART is returned if the current system
- * call should be restarted if possible, and EINTR is returned if the system
- * call should be interrupted by the signal (return EINTR).
- *
- * The mutex argument is exited before the caller is suspended, and
- * entered before msleep returns. If priority includes the PDROP
- * flag the mutex is not entered before returning.
- */
-static HANDLE msleep_glob_evt;
-
-void
-msleep_init (void)
-{
- msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (!msleep_glob_evt)
- panic ("CreateEvent in msleep_init failed: %E");
-}
-
-int
-_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);
-
- /* 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);
-
- 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_glob_evt,
- td->client->handle (),
- td->client->signal_arrived ()
- };
- /* PCATCH handling. If PCATCH is given and signal_arrived is a valid
- handle, then it's used in the WaitFor call and EINTR is returned. */
- int obj_cnt = 3;
- if ((priority & PCATCH)
- && td->client->signal_arrived () != INVALID_HANDLE_VALUE)
- obj_cnt = 4;
-
- switch (WaitForMultipleObjects (obj_cnt, obj, FALSE, timo ?: INFINITE))
- {
- case WAIT_OBJECT_0: /* wakeup() has been called. */
- ret = 0;
- 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. */
- ret = EIDRM;
- break;
- case WAIT_OBJECT_0 + 3: /* Signal for calling process arrived. */
- ret = EINTR;
- break;
- case WAIT_TIMEOUT:
- ret = EWOULDBLOCK;
- break;
- default:
- panic ("wait in msleep (%s) failed, %E", wmesg);
- 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);
-
- set_priority (old_priority);
-
- if (mtx && !(priority & PDROP))
- mtx_lock (mtx);
- return ret;
-}
-
-/*
- * Make all threads sleeping on the specified identifier runnable.
- */
-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);
-
- return 0;
-}
-
-/*
- * Wakeup all sleeping threads. Only called in the context of cygserver
- * shutdown.
- */
-void
-wakeup_all (void)
-{
- SetEvent (msleep_glob_evt);
-}
-#endif /* __OUTSIDE_CYGWIN__ */