- Cleanup the /lib directory, by putting more 3rd-party libs in /3rdparty, and by...
[reactos.git] / reactos / lib / sdk / crt / misc / lock.c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include <precomp.h>
20
21 #define NDEBUG
22 #include <internal/debug.h>
23 #include <internal/mtdll.h>
24
25 typedef struct
26 {
27 BOOL bInit;
28 CRITICAL_SECTION crit;
29 } LOCKTABLEENTRY;
30
31 static LOCKTABLEENTRY lock_table[ _TOTAL_LOCKS ];
32
33 static __inline void msvcrt_mlock_set_entry_initialized( int locknum, BOOL initialized )
34 {
35 lock_table[ locknum ].bInit = initialized;
36 }
37
38 static __inline void msvcrt_initialize_mlock( int locknum )
39 {
40 InitializeCriticalSection( &(lock_table[ locknum ].crit) );
41 msvcrt_mlock_set_entry_initialized( locknum, TRUE );
42 }
43
44 static __inline void msvcrt_uninitialize_mlock( int locknum )
45 {
46 DeleteCriticalSection( &(lock_table[ locknum ].crit) );
47 msvcrt_mlock_set_entry_initialized( locknum, FALSE );
48 }
49
50 /**********************************************************************
51 * msvcrt_init_mt_locks (internal)
52 *
53 * Initialize the table lock. All other locks will be initialized
54 * upon first use.
55 *
56 */
57 void msvcrt_init_mt_locks(void)
58 {
59 int i;
60
61 DPRINT( "initializing mtlocks\n" );
62
63 /* Initialize the table */
64 for( i=0; i < _TOTAL_LOCKS; i++ )
65 {
66 msvcrt_mlock_set_entry_initialized( i, FALSE );
67 }
68
69 /* Initialize our lock table lock */
70 msvcrt_initialize_mlock( _LOCKTAB_LOCK );
71 }
72
73 /**********************************************************************
74 * msvcrt_free_mt_locks (internal)
75 *
76 * Uninitialize all mt locks. Assume that neither _lock or _unlock will
77 * be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted)
78 *
79 */
80 void msvcrt_free_mt_locks(void)
81 {
82 int i;
83
84 DPRINT(": uninitializing all mtlocks\n" );
85
86 /* Uninitialize the table */
87 for( i=0; i < _TOTAL_LOCKS; i++ )
88 {
89 if( lock_table[ i ].bInit == TRUE )
90 {
91 msvcrt_uninitialize_mlock( i );
92 }
93 }
94 }
95
96
97 /**********************************************************************
98 * _lock (MSVCRT.@)
99 */
100 void _lock( int locknum )
101 {
102 DPRINT( "(%d)\n", locknum );
103
104 /* If the lock doesn't exist yet, create it */
105 if( lock_table[ locknum ].bInit == FALSE )
106 {
107 /* Lock while we're changing the lock table */
108 _lock( _LOCKTAB_LOCK );
109
110 /* Check again if we've got a bit of a race on lock creation */
111 if( lock_table[ locknum ].bInit == FALSE )
112 {
113 DPRINT( ": creating lock #%d\n", locknum );
114 msvcrt_initialize_mlock( locknum );
115 }
116
117 /* Unlock ourselves */
118 _unlock( _LOCKTAB_LOCK );
119 }
120
121 EnterCriticalSection( &(lock_table[ locknum ].crit) );
122 }
123
124 /**********************************************************************
125 * _unlock (MSVCRT.@)
126 *
127 * NOTE: There is no error detection to make sure the lock exists and is acquired.
128 */
129 void _unlock( int locknum )
130 {
131 DPRINT( "(%d)\n", locknum );
132
133 LeaveCriticalSection( &(lock_table[ locknum ].crit) );
134 }
135