diff options
Diffstat (limited to 'winsup/cygwin/sync.cc')
-rw-r--r-- | winsup/cygwin/sync.cc | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc deleted file mode 100644 index b6dec83..0000000 --- a/winsup/cygwin/sync.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* sync.cc: Synchronization functions for cygwin. - - This file implements the methods for controlling the "muto" class - which is intended to operate similarly to a mutex but attempts to - avoid making expensive calls to the kernel. - - Copyright 2000, 2001, 2002 Red Hat, Inc. - - Written by Christopher Faylor <cgf@cygnus.com> - -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. */ - -#include "winsup.h" -#include <stdlib.h> -#include <time.h> -#include <sys/wait.h> -#include <errno.h> -#include <stdlib.h> -#include "sync.h" -#include "security.h" - -muto NO_COPY muto_start; - -#undef WaitForSingleObject - -/* Constructor */ -muto * -muto::init (const char *s) -{ - waiters = -1; - /* Create event which is used in the fallback case when blocking is necessary */ - if (!(bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL))) - { - DWORD oerr = GetLastError (); - SetLastError (oerr); - return NULL; - } - name = s; - next = muto_start.next; - muto_start.next = this; - return this; -} - -#if 0 /* FIXME: Do we need this? mutos aren't destroyed until process exit */ -/* Destructor (racy?) */ -muto::~muto () -{ - while (visits) - release (); - - HANDLE h = bruteforce; - 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 - be handled correctly. - - Note: The goal here is to minimize, as much as possible, calls to the - OS. Hence the use of InterlockedIncrement, etc., rather than (much) more - expensive OS mutexes. */ -int -muto::acquire (DWORD ms) -{ - DWORD this_tid = GetCurrentThreadId (); - - if (tid != this_tid) - { - /* Increment the waiters part of the class. Need to do this first to - avoid potential races. */ - LONG was_waiting = InterlockedIncrement (&waiters); - - /* This is deceptively simple. Basically, it allows multiple attempts to - lock the same muto to succeed without attempting to manipulate sync. - If the muto is already locked then this thread will wait for ms until - it is signalled by muto::release. Then it will attempt to grab the - sync field. If it succeeds, then this thread owns the muto. - - There is a pathological condition where a thread times out waiting for - bruteforce but the release code triggers the bruteforce event. In this - 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. */ - if (tid != this_tid && (was_waiting || InterlockedExchange (&sync, 1) != 0)) - { - switch (WaitForSingleObject (bruteforce, ms)) - { - case WAIT_OBJECT_0: - goto gotit; - break; - default: - InterlockedDecrement (&waiters); - return 0; /* failed. */ - } - } - } - -gotit: - tid = this_tid; /* register this thread. */ - return ++visits; /* Increment visit count. */ -} - -/* Return the muto lock. Needs to be called once per every acquire. */ -int -muto::release () -{ - DWORD this_tid = GetCurrentThreadId (); - - if (tid != this_tid || !visits) - { - SetLastError (ERROR_NOT_OWNER); /* Didn't have the lock. */ - return 0; /* failed. */ - } - - /* FIXME: Need to check that other thread has not exited, too. */ - if (!--visits) - { - tid = 0; /* We were the last unlocker. */ - (void) InterlockedExchange (&sync, 0); /* Reset trigger. */ - /* This thread had incremented waiters but had never decremented it. - Decrement it now. If it is >= 0 then there are possibly other - threads waiting for the lock, so trigger bruteforce. */ - if (InterlockedDecrement (&waiters) >= 0) - (void) SetEvent (bruteforce); /* Wake up one of the waiting threads */ - } - - return 1; /* success. */ -} - -/* Call only when we're exiting. This is not thread safe. */ -void -muto::reset () -{ - visits = sync = tid = 0; - InterlockedExchange (&waiters, -1); - if (bruteforce) - { - CloseHandle (bruteforce); - bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, name); - } -} |