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.

76 lines
1.7 KiB

  1. /***
  2. *xlock.cpp - thread lock class
  3. *
  4. * Copyright (c) 1996-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Define lock class used to make STD C++ Library thread-safe.
  8. *
  9. *Revision History:
  10. * 08-28-96 GJF Module created, MGHMOM.
  11. *
  12. *******************************************************************************/
  13. #ifdef _MT
  14. #include <xstddef>
  15. #include <windows.h>
  16. _STD_BEGIN
  17. static CRITICAL_SECTION _CritSec;
  18. static long _InitFlag = 0L;
  19. static void _CleanUp()
  20. {
  21. long InitFlagValue;
  22. if ( InitFlagValue = InterlockedExchange( &_InitFlag, 3L ) == 2L )
  23. // Should be okay to delete critical section
  24. DeleteCriticalSection( &_CritSec );
  25. }
  26. _Lockit::_Lockit()
  27. {
  28. // Most common case - just enter the critical section
  29. if ( _InitFlag == 2L ) {
  30. EnterCriticalSection( &_CritSec );
  31. return;
  32. }
  33. // Critical section either needs to be initialized.
  34. if ( _InitFlag == 0L ) {
  35. long InitFlagVal;
  36. if ( (InitFlagVal = InterlockedExchange( &_InitFlag, 1L )) == 0L ) {
  37. InitializeCriticalSection( &_CritSec );
  38. atexit( _CleanUp );
  39. _InitFlag = 2L;
  40. }
  41. else if ( InitFlagVal == 2L )
  42. _InitFlag = 2L;
  43. }
  44. // If necessary, wait while another thread finishes initializing the
  45. // critical section
  46. while ( _InitFlag == 1L )
  47. Sleep( 1 );
  48. if ( _InitFlag == 2L )
  49. EnterCriticalSection( &_CritSec );
  50. }
  51. _Lockit::~_Lockit()
  52. {
  53. if ( _InitFlag == 2L )
  54. LeaveCriticalSection( &_CritSec );
  55. }
  56. _STD_END
  57. #endif