/* * Copyright (c) 2002, TransGaming Technologies Inc. */ #include "mtdll.h" #include "debugtools.h" #include "winbase.h" DEFAULT_DEBUG_CHANNEL(msvcrt); typedef struct { BOOL bInit; CRITICAL_SECTION crit; } LOCKTABLEENTRY; static LOCKTABLEENTRY lock_table[ _TOTAL_LOCKS ]; static inline void msvcrt_mlock_set_entry_initialized( int locknum, BOOL initialized ) { lock_table[ locknum ].bInit = initialized; } static inline void msvcrt_initialize_mlock( int locknum ) { InitializeCriticalSection( &(lock_table[ locknum ].crit) ); msvcrt_mlock_set_entry_initialized( locknum, TRUE ); } static inline void msvcrt_uninitialize_mlock( int locknum ) { DeleteCriticalSection( &(lock_table[ locknum ].crit) ); msvcrt_mlock_set_entry_initialized( locknum, FALSE ); } /********************************************************************** * msvcrt_init_mt_locks (internal) * * Initialize the table lock. All other locks will be initialized * upon first use. * */ void msvcrt_init_mt_locks(void) { int i; TRACE( "initializing mtlocks\n" ); /* Initialize the table */ for( i=0; i < _TOTAL_LOCKS; i++ ) { msvcrt_mlock_set_entry_initialized( i, FALSE ); } /* Initialize our lock table lock */ msvcrt_initialize_mlock( _LOCKTAB_LOCK ); } /********************************************************************** * msvcrt_free_mt_locks (internal) * * Uninitialize all mt locks. Assume that neither _lock or _unlock will * be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted) * */ void msvcrt_free_mt_locks(void) { int i; TRACE( ": uninitializing all mtlocks\n" ); /* Uninitialize the table */ for( i=0; i < _TOTAL_LOCKS; i++ ) { if( lock_table[ i ].bInit == TRUE ) { msvcrt_uninitialize_mlock( i ); } } } /********************************************************************** * _lock (MSVCRT.@) */ void _lock( int locknum ) { TRACE( "(%d)\n", locknum ); /* If the lock doesn't exist yet, create it */ if( lock_table[ locknum ].bInit == FALSE ) { /* Lock while we're changing the lock table */ _lock( _LOCKTAB_LOCK ); /* Check again if we've got a bit of a race on lock creation */ if( lock_table[ locknum ].bInit == FALSE ) { TRACE( ": creating lock #%d\n", locknum ); msvcrt_initialize_mlock( locknum ); } /* Unlock ourselves */ _unlock( _LOCKTAB_LOCK ); } EnterCriticalSection( &(lock_table[ locknum ].crit) ); } /********************************************************************** * _unlock (MSVCRT.@) * * NOTE: There is no error detection to make sure the lock exists and is acquired. */ void _unlock( int locknum ) { TRACE( "(%d)\n", locknum ); LeaveCriticalSection( &(lock_table[ locknum ].crit) ); }