Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.5 KiB

  1. #ifdef MTHREAD
  2. /***
  3. *mlock.c - Multi-thread locking routines
  4. *
  5. * Copyright (c) 1987-1993, Microsoft Corporation. All rights reserved.
  6. *
  7. *Purpose:
  8. *
  9. *Revision History:
  10. * 05-07-90 JCR Module created.
  11. * 06-04-90 GJF Changed error message interface.
  12. * 08-08-90 GJF Removed 32 from API names.
  13. * 08-08-90 SBM _lockmap no longer 8 times required size
  14. * 10-08-90 GJF New-style function declarators. Removed questionable
  15. * return statements from void functions (weren't needed
  16. * and the compiler was bitching).
  17. * 10-09-90 GJF Thread ids are unsigned longs.
  18. * 06-06-91 GJF Adapted for Win32 [_WIN32_].
  19. * 09-29-91 GJF Fixed infinite recursion problem with DEBUG version
  20. * of _lock [_WIN32_].
  21. * 03-06-92 GJF Removed _[un]lock_fh() and _[un]lock_stream for Win32
  22. * targets.
  23. * 05-28-92 GJF Added _mtdeletelocks() for Win32 for DLLs with contain
  24. * the C runtime (e.g., crtdll.dll).
  25. * 10-06-92 SRW Make _locktable an array of PCRITICAL_SECTION pointers
  26. * instead of structures. Allocate each critical section
  27. * as it is needed.
  28. * 02-25-93 GJF Substantially revised. Restored static critical section
  29. * structures for some locks. Replaced bit-array scheme
  30. * of keeping track of locks. Removed Cruiser support and
  31. * replaced obsolete DEBUG code.
  32. * 03-03-93 GJF Made CRITICAL_SECTION structure for _HEAP_LOCK static.
  33. * 03-08-93 SKS Fix ptr use error in DEBUG version of _mtdeletelocks
  34. * 03-08-93 SKS Fix deletion of the special critical sections,
  35. * especially the heap lock.
  36. * 05-05-93 GJF Turned DEBUG code off.
  37. * 06-03-93 SRW Disable FPO optimizations for this file so it can call
  38. * CriticalSection routines on a checked build even though
  39. * the C Runtimes are compiled free.
  40. *
  41. *******************************************************************************/
  42. #include <nt.h>
  43. #include <ntrtl.h>
  44. #include <nturtl.h>
  45. #include <windows.h>
  46. #include <cruntime.h>
  47. #include <internal.h>
  48. #include <os2dll.h>
  49. #include <assert.h>
  50. /*
  51. * Local routines
  52. */
  53. void __cdecl _lockerr_exit(char *);
  54. /*
  55. * Global Data
  56. */
  57. /*
  58. * Statically allocated critical section structures for _LOCKTAB_LOCK,
  59. * _EXIT_LOCK1.
  60. */
  61. static CRITICAL_SECTION xlcritsect;
  62. /*
  63. * Lock Table
  64. * This table contains a pointer to the critical section management structure
  65. * for each lock.
  66. */
  67. PCRITICAL_SECTION _locktable[_TOTAL_LOCKS] = {
  68. NULL, /* 0 == no lock defined *** OBSOLETE *** */
  69. &xlcritsect /* 1 == _EXIT_LOCK1 */
  70. };
  71. #pragma data_seg()
  72. #pragma optimize("y",off)
  73. /***
  74. *_mtinitlocks() - Initialize multi-thread lock scheme
  75. *
  76. *Purpose:
  77. * Perform whatever initialization is required for the multi-thread
  78. * locking (synchronization) scheme. This routine should be called
  79. * exactly once, during startup, and this must be before any requests
  80. * are made to assert locks.
  81. *
  82. * NOTES: In Win32, the multi-thread locks are created individually,
  83. * each upon its first use. That is when any particular lock is asserted
  84. * for the first time, the underlying critical section is then allocated,
  85. * initialized and (finally) entered. This allocation and initialization
  86. * is protected under _LOCKTAB_LOCK. It is _mtinitlocks' job to set up
  87. * _LOCKTAB_LOCK. _EXIT_LOCK1 is also set up by _mtinitlock
  88. *
  89. *Entry:
  90. * <none>
  91. *
  92. *Exit:
  93. * returns TRUE on success, FALSE otherwise
  94. *
  95. *Exceptions:
  96. *
  97. *******************************************************************************/
  98. int __cdecl _mtinitlocks (
  99. void
  100. )
  101. {
  102. /*
  103. * All we need to do is initialize _EXIT_LOCK1.
  104. */
  105. LONG status;
  106. status = RtlInitializeCriticalSection( _locktable[_EXIT_LOCK1] );
  107. return NT_SUCCESS(status) ? TRUE : FALSE;
  108. }
  109. /***
  110. *_mtdeletelocks() - Delete all initialized locks
  111. *
  112. *Purpose:
  113. * Walks _locktable[] and _lockmap, and deletes every 'lock' (i.e.,
  114. * critical section) which has been initialized.
  115. *
  116. * This function is intended for use in DLLs containing the C runtime
  117. * (i.e., crtdll.dll and user DLLs built using libcmt.lib and the
  118. * special startup objects). It is to be called from within the DLL's
  119. * entrypoint function when that function is called with
  120. * DLL_PROCESS_DETACH.
  121. *
  122. *Entry:
  123. * <none>
  124. *
  125. *Exit:
  126. *
  127. *Exceptions:
  128. * behavior undefined/unknown if a lock is being held when this routine
  129. * is called.
  130. *
  131. *******************************************************************************/
  132. void __cdecl _mtdeletelocks(
  133. void
  134. )
  135. {
  136. // No need to check for lock validity, this function will not get called
  137. // unless we successfully loaded the dll
  138. DeleteCriticalSection( _locktable[_EXIT_LOCK1] );
  139. }
  140. /***
  141. * _lock - Acquire a multi-thread lock
  142. *
  143. *Purpose:
  144. * Note that it is legal for a thread to aquire _EXIT_LOCK1
  145. * multiple times.
  146. *
  147. *Entry:
  148. * locknum = number of the lock to aquire
  149. *
  150. *Exit:
  151. *
  152. *Exceptions:
  153. *
  154. *******************************************************************************/
  155. void __cdecl _lock (
  156. int locknum
  157. )
  158. {
  159. assert (_locktable[locknum]);
  160. EnterCriticalSection( _locktable[locknum] );
  161. }
  162. /***
  163. * _unlock - Release multi-thread lock
  164. *
  165. *Purpose:
  166. * Note that it is legal for a thread to aquire _EXIT_LOCK1
  167. * multiple times.
  168. *
  169. *Entry:
  170. * locknum = number of the lock to release
  171. *
  172. *Exit:
  173. *
  174. *Exceptions:
  175. *
  176. *******************************************************************************/
  177. void __cdecl _unlock (
  178. int locknum
  179. )
  180. {
  181. /*
  182. * leave the critical section.
  183. */
  184. LeaveCriticalSection( _locktable[locknum] );
  185. }
  186. #pragma optimize("y",on)
  187. #endif /* MTHREAD */