1 /* 2 * Copyright (c) 2002, TransGaming Technologies Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include <precomp.h> 20 21 22 typedef struct 23 { 24 BOOL bInit; 25 CRITICAL_SECTION crit; 26 } LOCKTABLEENTRY; 27 28 static LOCKTABLEENTRY lock_table[ _TOTAL_LOCKS ]; 29 30 static __inline void msvcrt_mlock_set_entry_initialized( int locknum, BOOL initialized ) 31 { 32 lock_table[ locknum ].bInit = initialized; 33 } 34 35 static __inline void msvcrt_initialize_mlock( int locknum ) 36 { 37 InitializeCriticalSection( &(lock_table[ locknum ].crit) ); 38 msvcrt_mlock_set_entry_initialized( locknum, TRUE ); 39 } 40 41 static __inline void msvcrt_uninitialize_mlock( int locknum ) 42 { 43 DeleteCriticalSection( &(lock_table[ locknum ].crit) ); 44 msvcrt_mlock_set_entry_initialized( locknum, FALSE ); 45 } 46 47 /********************************************************************** 48 * msvcrt_init_mt_locks (internal) 49 * 50 * Initialize the table lock. All other locks will be initialized 51 * upon first use. 52 * 53 */ 54 void msvcrt_init_mt_locks(void) 55 { 56 int i; 57 58 TRACE( "initializing mtlocks\n" ); 59 60 /* Initialize the table */ 61 for( i=0; i < _TOTAL_LOCKS; i++ ) 62 { 63 msvcrt_mlock_set_entry_initialized( i, FALSE ); 64 } 65 66 /* Initialize our lock table lock */ 67 msvcrt_initialize_mlock( _LOCKTAB_LOCK ); 68 } 69 70 /********************************************************************** 71 * msvcrt_free_mt_locks (internal) 72 * 73 * Uninitialize all mt locks. Assume that neither _lock or _unlock will 74 * be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted) 75 * 76 */ 77 void msvcrt_free_mt_locks(void) 78 { 79 int i; 80 81 TRACE(": uninitializing all mtlocks\n" ); 82 83 /* Uninitialize the table */ 84 for( i=0; i < _TOTAL_LOCKS; i++ ) 85 { 86 if( lock_table[ i ].bInit ) 87 { 88 msvcrt_uninitialize_mlock( i ); 89 } 90 } 91 } 92 93 94 /********************************************************************** 95 * _lock (MSVCRT.@) 96 */ 97 void _lock( int locknum ) 98 { 99 TRACE( "(%d)\n", locknum ); 100 101 /* If the lock doesn't exist yet, create it */ 102 if( lock_table[ locknum ].bInit == FALSE ) 103 { 104 /* Lock while we're changing the lock table */ 105 _lock( _LOCKTAB_LOCK ); 106 107 /* Check again if we've got a bit of a race on lock creation */ 108 if( lock_table[ locknum ].bInit == FALSE ) 109 { 110 TRACE( ": creating lock #%d\n", locknum ); 111 msvcrt_initialize_mlock( locknum ); 112 } 113 114 /* Unlock ourselves */ 115 _unlock( _LOCKTAB_LOCK ); 116 } 117 118 EnterCriticalSection( &(lock_table[ locknum ].crit) ); 119 } 120 121 /********************************************************************** 122 * _unlock (MSVCRT.@) 123 * 124 * NOTE: There is no error detection to make sure the lock exists and is acquired. 125 */ 126 void _unlock( int locknum ) 127 { 128 TRACE( "(%d)\n", locknum ); 129 130 LeaveCriticalSection( &(lock_table[ locknum ].crit) ); 131 } 132 133 134