213 lines
5.5 KiB
C
213 lines
5.5 KiB
C
#ifdef MTHREAD
|
|
|
|
/***
|
|
*mlock.c - Multi-thread locking routines
|
|
*
|
|
* Copyright (c) 1987-1993, Microsoft Corporation. All rights reserved.
|
|
*
|
|
*Purpose:
|
|
*
|
|
*Revision History:
|
|
* 05-07-90 JCR Module created.
|
|
* 06-04-90 GJF Changed error message interface.
|
|
* 08-08-90 GJF Removed 32 from API names.
|
|
* 08-08-90 SBM _lockmap no longer 8 times required size
|
|
* 10-08-90 GJF New-style function declarators. Removed questionable
|
|
* return statements from void functions (weren't needed
|
|
* and the compiler was bitching).
|
|
* 10-09-90 GJF Thread ids are unsigned longs.
|
|
* 06-06-91 GJF Adapted for Win32 [_WIN32_].
|
|
* 09-29-91 GJF Fixed infinite recursion problem with DEBUG version
|
|
* of _lock [_WIN32_].
|
|
* 03-06-92 GJF Removed _[un]lock_fh() and _[un]lock_stream for Win32
|
|
* targets.
|
|
* 05-28-92 GJF Added _mtdeletelocks() for Win32 for DLLs with contain
|
|
* the C runtime (e.g., crtdll.dll).
|
|
* 10-06-92 SRW Make _locktable an array of PCRITICAL_SECTION pointers
|
|
* instead of structures. Allocate each critical section
|
|
* as it is needed.
|
|
* 02-25-93 GJF Substantially revised. Restored static critical section
|
|
* structures for some locks. Replaced bit-array scheme
|
|
* of keeping track of locks. Removed Cruiser support and
|
|
* replaced obsolete DEBUG code.
|
|
* 03-03-93 GJF Made CRITICAL_SECTION structure for _HEAP_LOCK static.
|
|
* 03-08-93 SKS Fix ptr use error in DEBUG version of _mtdeletelocks
|
|
* 03-08-93 SKS Fix deletion of the special critical sections,
|
|
* especially the heap lock.
|
|
* 05-05-93 GJF Turned DEBUG code off.
|
|
* 06-03-93 SRW Disable FPO optimizations for this file so it can call
|
|
* CriticalSection routines on a checked build even though
|
|
* the C Runtimes are compiled free.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <cruntime.h>
|
|
#include <internal.h>
|
|
#include <os2dll.h>
|
|
#include <assert.h>
|
|
|
|
|
|
/*
|
|
* Local routines
|
|
*/
|
|
void __cdecl _lockerr_exit(char *);
|
|
|
|
|
|
/*
|
|
* Global Data
|
|
*/
|
|
|
|
/*
|
|
* Statically allocated critical section structures for _LOCKTAB_LOCK,
|
|
* _EXIT_LOCK1.
|
|
*/
|
|
static CRITICAL_SECTION xlcritsect;
|
|
|
|
/*
|
|
* Lock Table
|
|
* This table contains a pointer to the critical section management structure
|
|
* for each lock.
|
|
*/
|
|
PCRITICAL_SECTION _locktable[_TOTAL_LOCKS] = {
|
|
NULL, /* 0 == no lock defined *** OBSOLETE *** */
|
|
&xlcritsect /* 1 == _EXIT_LOCK1 */
|
|
};
|
|
|
|
#pragma data_seg()
|
|
|
|
#pragma optimize("y",off)
|
|
|
|
/***
|
|
*_mtinitlocks() - Initialize multi-thread lock scheme
|
|
*
|
|
*Purpose:
|
|
* Perform whatever initialization is required for the multi-thread
|
|
* locking (synchronization) scheme. This routine should be called
|
|
* exactly once, during startup, and this must be before any requests
|
|
* are made to assert locks.
|
|
*
|
|
* NOTES: In Win32, the multi-thread locks are created individually,
|
|
* each upon its first use. That is when any particular lock is asserted
|
|
* for the first time, the underlying critical section is then allocated,
|
|
* initialized and (finally) entered. This allocation and initialization
|
|
* is protected under _LOCKTAB_LOCK. It is _mtinitlocks' job to set up
|
|
* _LOCKTAB_LOCK. _EXIT_LOCK1 is also set up by _mtinitlock
|
|
*
|
|
*Entry:
|
|
* <none>
|
|
*
|
|
*Exit:
|
|
* returns TRUE on success, FALSE otherwise
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
int __cdecl _mtinitlocks (
|
|
void
|
|
)
|
|
{
|
|
|
|
/*
|
|
* All we need to do is initialize _EXIT_LOCK1.
|
|
*/
|
|
LONG status;
|
|
status = RtlInitializeCriticalSection( _locktable[_EXIT_LOCK1] );
|
|
return NT_SUCCESS(status) ? TRUE : FALSE;
|
|
}
|
|
|
|
|
|
/***
|
|
*_mtdeletelocks() - Delete all initialized locks
|
|
*
|
|
*Purpose:
|
|
* Walks _locktable[] and _lockmap, and deletes every 'lock' (i.e.,
|
|
* critical section) which has been initialized.
|
|
*
|
|
* This function is intended for use in DLLs containing the C runtime
|
|
* (i.e., crtdll.dll and user DLLs built using libcmt.lib and the
|
|
* special startup objects). It is to be called from within the DLL's
|
|
* entrypoint function when that function is called with
|
|
* DLL_PROCESS_DETACH.
|
|
*
|
|
*Entry:
|
|
* <none>
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
* behavior undefined/unknown if a lock is being held when this routine
|
|
* is called.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
void __cdecl _mtdeletelocks(
|
|
void
|
|
)
|
|
{
|
|
// No need to check for lock validity, this function will not get called
|
|
// unless we successfully loaded the dll
|
|
DeleteCriticalSection( _locktable[_EXIT_LOCK1] );
|
|
}
|
|
|
|
|
|
/***
|
|
* _lock - Acquire a multi-thread lock
|
|
*
|
|
*Purpose:
|
|
* Note that it is legal for a thread to aquire _EXIT_LOCK1
|
|
* multiple times.
|
|
*
|
|
*Entry:
|
|
* locknum = number of the lock to aquire
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
void __cdecl _lock (
|
|
int locknum
|
|
)
|
|
{
|
|
assert (_locktable[locknum]);
|
|
|
|
EnterCriticalSection( _locktable[locknum] );
|
|
}
|
|
|
|
|
|
/***
|
|
* _unlock - Release multi-thread lock
|
|
*
|
|
*Purpose:
|
|
* Note that it is legal for a thread to aquire _EXIT_LOCK1
|
|
* multiple times.
|
|
*
|
|
*Entry:
|
|
* locknum = number of the lock to release
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
void __cdecl _unlock (
|
|
int locknum
|
|
)
|
|
{
|
|
/*
|
|
* leave the critical section.
|
|
*/
|
|
LeaveCriticalSection( _locktable[locknum] );
|
|
}
|
|
|
|
#pragma optimize("y",on)
|
|
|
|
#endif /* MTHREAD */
|