diff options
author | Ranjit Mathew <rmathew@hotmail.com> | 2003-01-28 22:23:36 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2003-01-28 22:23:36 +0000 |
commit | 65b8e87409edd85c85352d333c39efb90d7cd80c (patch) | |
tree | 574bb63340f70c9fa5bf9c43614d3646628d128e /libjava/win32-threads.cc | |
parent | c1c1d12306906a61f3c0f9f5956723a1d0f407dd (diff) | |
download | gcc-65b8e87409edd85c85352d333c39efb90d7cd80c.zip gcc-65b8e87409edd85c85352d333c39efb90d7cd80c.tar.gz gcc-65b8e87409edd85c85352d333c39efb90d7cd80c.tar.bz2 |
re PR java/9254 (java::lang::Object::wait(), threads-win32.cc returns wrong return codes)
2003-01-28 Ranjit Mathew <rmathew@hotmail.com>
Fixes PR java/9254:
* include/win32-threads.h (_Jv_Mutex_t): Convert to a struct
additionally containing id of the owner thread as well as
the number of nested times the thread has acquired the mutex.
(_Jv_MutexInit): Initialise owner thread id and refcount to 0.
(_Jv_MutexDestroy): Reset owner thread id and refcount to 0.
(_Jv_MutexUnlock): Check if really the owner thread, reset
owner thread id to 0 before leaving, if leaving for the last
time.
(_Jv_MutexLock): Set owner thread id in the mutex and increment
refcount.
(_Jv_ThreadYield): Yield using a call to Sleep(0).
* win32-threads.cc (_Jv_CondWait): Check if really owner of
the passed mutex.
Pass handle of the broadcast event, instead of a pointer to it
in Win32 ResetEvent( ) call.
Remove incorrect return values.
(_Jv_CondDestroy): Close both event handles and delete
critical section.
(_Jv_CondNotify): Check if really the owner thread.
(_Jv_CondNotifyAll): Check if really the owner thread.
(_Jv_InitThreads): Change daemon_cond to a manual-reset event.
(really_start): Use SetEvent( ) to signal daemon_cond.
(_Jv_ThreadWait): Remove SignalObjectAndWait( ) and use
WaitForSingleObject( ) instead to wait for daemon_cond to be
signalled.
From-SVN: r62033
Diffstat (limited to 'libjava/win32-threads.cc')
-rw-r--r-- | libjava/win32-threads.cc | 101 |
1 files changed, 62 insertions, 39 deletions
diff --git a/libjava/win32-threads.cc b/libjava/win32-threads.cc index d31c191..3a3999a 100644 --- a/libjava/win32-threads.cc +++ b/libjava/win32-threads.cc @@ -1,6 +1,7 @@ // win32-threads.cc - interface between libjava and Win32 threads. -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software + Foundation, Inc. This file is part of libgcj. @@ -70,12 +71,14 @@ DWORD _Jv_ThreadDataKey; inline void ensure_condvar_initialized(_Jv_ConditionVariable_t *cv) { - if (cv->ev[0] == 0) { - cv->ev[0] = CreateEvent (NULL, 0, 0, NULL); - if (cv->ev[0] == 0) JvFail("CreateEvent() failed"); - cv->ev[1] = CreateEvent (NULL, 1, 0, NULL); - if (cv->ev[1] == 0) JvFail("CreateEvent() failed"); - } + if (cv->ev[0] == 0) + { + cv->ev[0] = CreateEvent (NULL, 0, 0, NULL); + if (cv->ev[0] == 0) JvFail("CreateEvent() failed"); + + cv->ev[1] = CreateEvent (NULL, 1, 0, NULL); + if (cv->ev[1] == 0) JvFail("CreateEvent() failed"); + } } // Reimplementation of the general algorithm described at @@ -85,11 +88,13 @@ ensure_condvar_initialized(_Jv_ConditionVariable_t *cv) int _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos) { + if (mu->owner != GetCurrentThreadId ( )) + return _JV_NOT_OWNER; - EnterCriticalSection(&cv->count_mutex); - ensure_condvar_initialized(cv); + EnterCriticalSection (&cv->count_mutex); + ensure_condvar_initialized (cv); cv->blocked_count++; - LeaveCriticalSection(&cv->count_mutex); + LeaveCriticalSection (&cv->count_mutex); DWORD time; if ((millis == 0) && (nanos > 0)) time = 1; @@ -102,18 +107,17 @@ _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint na EnterCriticalSection(&cv->count_mutex); cv->blocked_count--; - // If we were unblocked by the second event (the broadcast one) and nobody is - // left, then reset the signal. - int last_waiter = rval == WAIT_OBJECT_0 + 1 && cv->blocked_count == 0; + // If we were unblocked by the second event (the broadcast one) + // and nobody is left, then reset the event. + int last_waiter = (rval == (WAIT_OBJECT_0 + 1)) && (cv->blocked_count == 0); LeaveCriticalSection(&cv->count_mutex); - if (last_waiter) ResetEvent(&cv->ev[1]); + if (last_waiter) + ResetEvent (cv->ev[1]); _Jv_MutexLock (mu); - if (rval == WAIT_FAILED) return GetLastError(); - else if (rval == WAIT_TIMEOUT) return ETIMEDOUT; - else return 0; + return 0; } void @@ -121,39 +125,56 @@ _Jv_CondInit (_Jv_ConditionVariable_t *cv) { // we do lazy creation of Events since CreateEvent() is insanely expensive cv->ev[0] = 0; - InitializeCriticalSection(&cv->count_mutex); + InitializeCriticalSection (&cv->count_mutex); cv->blocked_count = 0; } void _Jv_CondDestroy (_Jv_ConditionVariable_t *cv) { - if (cv->ev[0] != 0) CloseHandle(cv->ev[0]); - cv = NULL; + if (cv->ev[0] != 0) + { + CloseHandle (cv->ev[0]); + CloseHandle (cv->ev[1]); + + cv->ev[0] = 0; + } + + DeleteCriticalSection (&cv->count_mutex); } int -_Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *) +_Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) { - EnterCriticalSection(&cv->count_mutex); - ensure_condvar_initialized(cv); + if (mu->owner != GetCurrentThreadId ( )) + return _JV_NOT_OWNER; + + EnterCriticalSection (&cv->count_mutex); + ensure_condvar_initialized (cv); int somebody_is_blocked = cv->blocked_count > 0; - LeaveCriticalSection(&cv->count_mutex); + LeaveCriticalSection (&cv->count_mutex); + + if (somebody_is_blocked) + SetEvent (cv->ev[0]); - if (somebody_is_blocked) return SetEvent (cv->ev[0]) ? 0 : GetLastError(); - else return 0; + return 0; } int -_Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *) +_Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) { - EnterCriticalSection(&cv->count_mutex); - ensure_condvar_initialized(cv); + if (mu->owner != GetCurrentThreadId ( )) + return _JV_NOT_OWNER; + + EnterCriticalSection (&cv->count_mutex); + ensure_condvar_initialized (cv); int somebody_is_blocked = cv->blocked_count > 0; - LeaveCriticalSection(&cv->count_mutex); + LeaveCriticalSection (&cv->count_mutex); - if (somebody_is_blocked) return SetEvent (cv->ev[1]) ? 0 : GetLastError(); - else return 0; + if (somebody_is_blocked) + SetEvent (cv->ev[1]); + + return 0; } // @@ -165,8 +186,8 @@ _Jv_InitThreads (void) { _Jv_ThreadKey = TlsAlloc(); _Jv_ThreadDataKey = TlsAlloc(); - daemon_mutex = CreateMutex(NULL, 0, NULL); - daemon_cond = CreateEvent(NULL, 0, 0, NULL); + daemon_mutex = CreateMutex (NULL, 0, NULL); + daemon_cond = CreateEvent (NULL, 1, 0, NULL); non_daemon_count = 0; } @@ -255,7 +276,7 @@ really_start (void* x) WaitForSingleObject (daemon_mutex, INFINITE); non_daemon_count--; if (! non_daemon_count) - PulseEvent (daemon_cond); + SetEvent (daemon_cond); ReleaseMutex (daemon_mutex); } @@ -297,10 +318,12 @@ _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStart void _Jv_ThreadWait (void) { - WaitForSingleObject(daemon_mutex, INFINITE); - if(non_daemon_count) - SignalObjectAndWait(daemon_mutex, daemon_cond, INFINITE, 0); - ReleaseMutex(daemon_mutex); + WaitForSingleObject (daemon_mutex, INFINITE); + if (non_daemon_count) + { + ReleaseMutex (daemon_mutex); + WaitForSingleObject (daemon_cond, INFINITE); + } } void |