From 40aac94801f86355bd86cf5b340481ee2f501d3c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 27 Aug 2004 22:33:54 -0400 Subject: re PR c++/13684 (local static object variable constructed once but ctors and dtors called multiple times on same memory when called in multiple threads) PR c++/13684 * cp/decl.c (expand_static_init): Use thread-safety API. (register_dtor_fn): Return the call, don't expand it. * cp/tree.c (add_stmt_to_compound): New fn. (stabilize_call): Use it. * gimplify.c (gimplify_cleanup_point_expr): Handle CLEANUP_EH_ONLY. (gimple_push_cleanup): Add eh_only parm. (gimplify_target_expr): Pass it. * c.opt (-fno-threadsafe-statics): New option. * c-opts.c (c_common_handle_option): Handle it. * c-common.h (flag_threadsafe_statics): Declare it. * c-common.c (flag_threadsafe_statics): Record it. * doc/invoke.texi: Document it. * tsystem.h (_GNU_SOURCE): Define. * gthr-posix.h (__gthread_recursive_mutex_t): New typedef. (__GTHREAD_RECURSIVE_MUTEX_INIT): New macro. (__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION): New macro. (__gthread_recursive_mutex_init_function): New fn. (__gthread_recursive_mutex_lock): New fn. (__gthread_recursive_mutex_trylock): New fn. (__gthread_recursive_mutex_unlock): New fn. * gthr-solaris.h, gthr-single.h, gthr-dce.h: Likewise. * gthr-win32.h, gthr-vxworks.h: Likewise. * gthr.h: Document. * libsupc++/guard.cc (static_mutex): Internal class implementing a recursive mutex which controls initialization of local statics. (__gnu_cxx::recursive_init): New exception class. (__cxa_guard_acquire): Deal with locking and recursion detection. (acquire_1, __cxa_guard_abort, __cxa_guard_release): Likewise. From-SVN: r86687 --- gcc/config/i386/gthr-win32.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'gcc/config/i386/gthr-win32.c') diff --git a/gcc/config/i386/gthr-win32.c b/gcc/config/i386/gthr-win32.c index c53369b..6fb3cf8 100644 --- a/gcc/config/i386/gthr-win32.c +++ b/gcc/config/i386/gthr-win32.c @@ -182,3 +182,73 @@ __gthr_win32_mutex_unlock (__gthread_mutex_t *mutex) else return 0; } + +void +__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) +{ + mutex->counter = -1; + mutex->depth = 0; + mutex->owner = 0; + mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); +} + +int +__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) +{ + DWORD me = GetCurrentThreadId(); + if (InterlockedIncrement (&mutex->counter) == 0) + { + mutex->depth = 1; + mutex->owner = me; + } + else if (mutex->owner == me) + { + InterlockedDecrement (&mx->lock_idx); + ++(mutex->depth); + } + else if (WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) + { + mutex->depth = 1; + mutex->owner = me; + } + else + { + /* WaitForSingleObject returns WAIT_FAILED, and we can only do + some best-effort cleanup here. */ + InterlockedDecrement (&mutex->counter); + return 1; + } + return 0; +} + +int +__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) +{ + DWORD me = GetCurrentThreadId(); + if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0) + { + mutex->depth = 1; + mutex->owner = me; + } + else if (mutex->owner == me) + ++(mutex->depth); + else + return 1; + + return 0; +} + +int +__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) +{ + --(mutex->depth); + if (mutex->depth == 0) + { + mutex->owner = 0; + + if (InterlockedDecrement (&mutex->counter) >= 0) + return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; + } + + return 0; +} -- cgit v1.1