1999-08-16 21:50:52 +00:00
|
|
|
/*
|
2001-03-21 20:44:20 +00:00
|
|
|
******************************************************************************
|
2000-01-13 23:54:23 +00:00
|
|
|
*
|
2001-03-21 20:44:20 +00:00
|
|
|
* Copyright (C) 1997-2001, International Business Machines
|
2000-01-13 23:54:23 +00:00
|
|
|
* Corporation and others. All Rights Reserved.
|
|
|
|
*
|
2001-03-21 20:44:20 +00:00
|
|
|
******************************************************************************
|
1999-08-16 21:50:52 +00:00
|
|
|
*
|
|
|
|
* File CMUTEX.C
|
|
|
|
*
|
|
|
|
* Modification History:
|
|
|
|
*
|
|
|
|
* Date Name Description
|
|
|
|
* 04/02/97 aliu Creation.
|
|
|
|
* 04/07/99 srl updated
|
|
|
|
* 05/13/99 stephen Changed to umutex (from cmutex).
|
1999-11-22 16:24:43 +00:00
|
|
|
* 11/22/99 aliu Make non-global mutex autoinitialize [j151]
|
2001-03-21 20:44:20 +00:00
|
|
|
******************************************************************************
|
1999-08-16 21:50:52 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Assume POSIX, and modify as necessary below */
|
|
|
|
#define POSIX
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
#undef POSIX
|
|
|
|
#endif
|
|
|
|
#if defined(macintosh)
|
|
|
|
#undef POSIX
|
|
|
|
#endif
|
|
|
|
#if defined(OS2)
|
|
|
|
#undef POSIX
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
1999-12-09 23:11:48 +00:00
|
|
|
/* Check our settings... */
|
1999-12-28 23:39:02 +00:00
|
|
|
#include "unicode/utypes.h"
|
1999-12-09 23:11:48 +00:00
|
|
|
|
|
|
|
/* APP_NO_THREADS is an old symbol. We'll honour it if present. */
|
|
|
|
#ifdef APP_NO_THREADS
|
|
|
|
# define ICU_USE_THREADS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Default: use threads. */
|
|
|
|
#ifndef ICU_USE_THREADS
|
|
|
|
# define ICU_USE_THREADS 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(POSIX) && (ICU_USE_THREADS==1)
|
1999-08-16 21:50:52 +00:00
|
|
|
/* Usage: uncomment the following, and breakpoint WeAreDeadlocked to
|
|
|
|
find reentrant issues. */
|
|
|
|
/* # define POSIX_DEBUG_REENTRANCY 1 */
|
|
|
|
# include <pthread.h> /* must be first, so that we get the multithread versions of things. */
|
|
|
|
|
|
|
|
# ifdef POSIX_DEBUG_REENTRANCY
|
|
|
|
pthread_t gLastThread;
|
2000-05-18 22:08:39 +00:00
|
|
|
UBool gInMutex;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
|
|
U_EXPORT void WeAreDeadlocked();
|
|
|
|
|
|
|
|
void WeAreDeadlocked()
|
|
|
|
{
|
|
|
|
puts("ARGH!! We're deadlocked.. break on WeAreDeadlocked() next time.");
|
|
|
|
}
|
|
|
|
# endif /* POSIX_DEBUG_REENTRANCY */
|
1999-12-09 23:11:48 +00:00
|
|
|
#endif /* POSIX && (ICU_USE_THREADS==1) */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
2000-10-05 15:54:16 +00:00
|
|
|
#ifdef WIN32
|
2001-06-26 17:53:36 +00:00
|
|
|
# define WIN32_LEAN_AND_MEAN
|
2001-06-27 16:25:02 +00:00
|
|
|
# define NOGDI
|
2001-06-26 17:53:36 +00:00
|
|
|
# define NOUSER
|
|
|
|
# define NOSERVICE
|
|
|
|
# define NOIME
|
|
|
|
# define NOMCX
|
|
|
|
# include <windows.h>
|
1999-08-16 21:50:52 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "umutex.h"
|
1999-10-12 00:07:24 +00:00
|
|
|
#include "cmemory.h"
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
|
|
/* the global mutex. Use it proudly and wash it often. */
|
|
|
|
UMTX gGlobalMutex = NULL;
|
|
|
|
|
|
|
|
void umtx_lock( UMTX *mutex )
|
|
|
|
{
|
1999-12-09 23:11:48 +00:00
|
|
|
#if (ICU_USE_THREADS == 1)
|
1999-08-16 21:50:52 +00:00
|
|
|
if( mutex == NULL )
|
|
|
|
{
|
|
|
|
mutex = &gGlobalMutex;
|
1999-11-22 16:24:43 +00:00
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
1999-11-22 16:24:43 +00:00
|
|
|
if(*mutex == NULL)
|
|
|
|
{
|
1999-11-22 17:23:31 +00:00
|
|
|
umtx_init(mutex);
|
1999-08-16 21:50:52 +00:00
|
|
|
}
|
|
|
|
|
2000-10-05 15:54:16 +00:00
|
|
|
#if defined(WIN32)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
|
|
EnterCriticalSection((CRITICAL_SECTION*) *mutex);
|
|
|
|
|
|
|
|
#elif defined(POSIX)
|
|
|
|
|
|
|
|
# ifdef POSIX_DEBUG_REENTRANCY
|
1999-12-10 18:13:22 +00:00
|
|
|
if(gInMutex == TRUE) /* in the mutex -- possible deadlock*/
|
1999-08-16 21:50:52 +00:00
|
|
|
if(pthread_equal(gLastThread,pthread_self()))
|
|
|
|
WeAreDeadlocked();
|
|
|
|
# endif
|
|
|
|
|
|
|
|
pthread_mutex_lock((pthread_mutex_t*) *mutex);
|
|
|
|
|
|
|
|
# ifdef POSIX_DEBUG_REENTRANCY
|
|
|
|
gLastThread = pthread_self();
|
|
|
|
gInMutex = TRUE;
|
|
|
|
# endif
|
|
|
|
#endif
|
1999-12-09 23:11:48 +00:00
|
|
|
#endif /* ICU_USE_THREADS==1 */
|
1999-08-16 21:50:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void umtx_unlock( UMTX* mutex )
|
|
|
|
{
|
1999-12-09 23:11:48 +00:00
|
|
|
#if (ICU_USE_THREADS==1)
|
1999-08-16 21:50:52 +00:00
|
|
|
if( mutex == NULL )
|
|
|
|
{
|
|
|
|
mutex = &gGlobalMutex;
|
|
|
|
|
|
|
|
if(*mutex == NULL)
|
|
|
|
{
|
1999-11-05 20:02:42 +00:00
|
|
|
return; /* jitterbug 135, fix for multiprocessor machines */
|
1999-08-16 21:50:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-05 15:54:16 +00:00
|
|
|
#if defined(WIN32)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
|
|
LeaveCriticalSection((CRITICAL_SECTION*)*mutex);
|
|
|
|
|
|
|
|
#elif defined(POSIX)
|
|
|
|
pthread_mutex_unlock((pthread_mutex_t*)*mutex);
|
|
|
|
#ifdef POSIX_DEBUG_REENTRANCY
|
|
|
|
gInMutex = FALSE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
1999-12-09 23:11:48 +00:00
|
|
|
#endif /* ICU_USE_THREADS == 1 */
|
1999-08-16 21:50:52 +00:00
|
|
|
}
|
|
|
|
|
1999-10-18 22:48:32 +00:00
|
|
|
U_CAPI void umtx_init( UMTX *mutex )
|
1999-08-16 21:50:52 +00:00
|
|
|
{
|
1999-12-09 23:11:48 +00:00
|
|
|
#if (ICU_USE_THREADS == 1)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
|
|
if( mutex == NULL ) /* initialize the global mutex */
|
|
|
|
{
|
|
|
|
mutex = &gGlobalMutex;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(*mutex != NULL) /* someone already did it. */
|
|
|
|
return;
|
|
|
|
|
2000-10-05 15:54:16 +00:00
|
|
|
#if defined(WIN32)
|
1999-12-28 23:39:02 +00:00
|
|
|
*mutex = uprv_malloc(sizeof(CRITICAL_SECTION));
|
1999-08-16 21:50:52 +00:00
|
|
|
InitializeCriticalSection((CRITICAL_SECTION*)*mutex);
|
|
|
|
|
|
|
|
#elif defined( POSIX )
|
|
|
|
|
1999-12-28 23:39:02 +00:00
|
|
|
*mutex = uprv_malloc(sizeof(pthread_mutex_t));
|
1999-08-16 21:50:52 +00:00
|
|
|
|
2000-01-17 22:22:29 +00:00
|
|
|
#if defined(HPUX_CMA)
|
1999-08-16 21:50:52 +00:00
|
|
|
pthread_mutex_init((pthread_mutex_t*)*mutex, pthread_mutexattr_default);
|
|
|
|
#else
|
|
|
|
pthread_mutex_init((pthread_mutex_t*)*mutex,NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
# ifdef POSIX_DEBUG_REENTRANCY
|
|
|
|
gInMutex = FALSE;
|
|
|
|
# endif
|
|
|
|
|
|
|
|
#endif
|
1999-12-09 23:11:48 +00:00
|
|
|
#endif /* ICU_USE_THREADS==1 */
|
1999-08-16 21:50:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|