From 65b8e87409edd85c85352d333c39efb90d7cd80c Mon Sep 17 00:00:00 2001 From: Ranjit Mathew Date: Tue, 28 Jan 2003 22:23:36 +0000 Subject: re PR java/9254 (java::lang::Object::wait(), threads-win32.cc returns wrong return codes) 2003-01-28 Ranjit Mathew 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 --- libjava/include/win32-threads.h | 58 ++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'libjava/include/win32-threads.h') diff --git a/libjava/include/win32-threads.h b/libjava/include/win32-threads.h index e8cf805..5e40ae2 100644 --- a/libjava/include/win32-threads.h +++ b/libjava/include/win32-threads.h @@ -1,7 +1,8 @@ // -*- c++ -*- // win32-threads.h - Defines for using Win32 threads. -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software + Foundation This file is part of libgcj. @@ -18,13 +19,32 @@ details. */ // Typedefs. // -typedef struct _Jv_ConditionVariable_t { +typedef struct +{ + // ev[0] (signal) is a Win32 auto-reset event for _Jv_CondNotify + // ev[1] (broadcast) is a Win32 manual-reset event for _Jv_CondNotifyAll HANDLE ev[2]; - CRITICAL_SECTION count_mutex; + + // Number of threads waiting on this condition variable int blocked_count; -}; -typedef CRITICAL_SECTION _Jv_Mutex_t; + // Protects access to the blocked_count variable + CRITICAL_SECTION count_mutex; + +} _Jv_ConditionVariable_t; + +typedef struct +{ + // The thread-id of the owner thread if any, 0 otherwise + DWORD owner; + + // Track nested mutex acquisitions by the same thread + int refcount; + + // The actual Windows construct used to implement this mutex + CRITICAL_SECTION cs; + +} _Jv_Mutex_t; typedef struct { @@ -60,25 +80,39 @@ int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *); inline void _Jv_MutexInit (_Jv_Mutex_t *mu) { - InitializeCriticalSection(mu); + mu->owner = 0UL; + mu->refcount = 0; + InitializeCriticalSection (&(mu->cs)); } #define _Jv_HaveMutexDestroy inline void _Jv_MutexDestroy (_Jv_Mutex_t *mu) { - DeleteCriticalSection(mu); + mu->owner = 0UL; + mu->refcount = 0; + DeleteCriticalSection (&(mu->cs)); mu = NULL; } inline int _Jv_MutexUnlock (_Jv_Mutex_t *mu) { - LeaveCriticalSection(mu); - return 0; + if (mu->owner == GetCurrentThreadId ( )) + { + mu->refcount--; + if (mu->refcount == 0) + mu->owner = 0UL; + LeaveCriticalSection (&(mu->cs)); + return 0; + } + else + return 1; } inline int _Jv_MutexLock (_Jv_Mutex_t *mu) { - EnterCriticalSection(mu); + EnterCriticalSection (&(mu->cs)); + mu->owner = GetCurrentThreadId ( ); + mu->refcount++; return 0; } @@ -104,9 +138,7 @@ inline _Jv_Thread_t *_Jv_ThreadCurrentData(void) inline void _Jv_ThreadYield (void) { - // FIXME: win98 freezes hard (OS hang) when we use this -- - // for now, we simply don't yield - // Sleep (0); + Sleep (0); } void _Jv_ThreadRegister (_Jv_Thread_t *data); -- cgit v1.1