critsec.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #ifndef _CRITSEC_H
  2. #define _CRITSEC_H
  3. #ifdef _WIN32
  4. #include <windows.h>
  5. #elif defined(__APPLE__)
  6. #include <CoreServices/CoreServices.h>
  7. #endif
  8. #include <bfc/common.h>
  9. #include <bfc/bfc_assert.h>
  10. /**
  11. CriticalSection is a portable object that implements a critical section,
  12. which is to say, it ensures that no two threads can be in that same
  13. section of code at the same time. Usually you make them a global object
  14. or allocate them with new and pass them to both threads.
  15. @short Critical section class.
  16. @author Nullsoft
  17. @ver 1.0
  18. @see Thread
  19. @see InCriticalSection
  20. */
  21. class CriticalSection {
  22. public:
  23. CriticalSection();
  24. virtual ~CriticalSection();
  25. /**
  26. Enters the critical section. If another thread is already in the critical
  27. section, the calling thread will be blocked until the other thread calls
  28. leave().
  29. @see leave()
  30. */
  31. void enter();
  32. /**
  33. Leaves the critical section. If another thread is currently blocked on
  34. this critical section, it will be unblocked. If multiple threads are blocking
  35. only one will be unblocked.
  36. @see enter()
  37. */
  38. void leave();
  39. /**
  40. Calls enter() and leave() in quick succession. Useful to make sure that no
  41. other thread is in the critical section (although another thread could
  42. immediately re-enter)
  43. @see enter()
  44. @see leave()
  45. */
  46. void inout();
  47. private:
  48. #ifdef ASSERTS_ENABLED
  49. int within;
  50. #endif
  51. #ifdef _WIN32
  52. CRITICAL_SECTION cs;
  53. #elif defined(__APPLE__)
  54. MPCriticalRegionID cr;
  55. #endif
  56. };
  57. /**
  58. This is a little helper class to ease the use of class CriticalSection.
  59. When it is instantiated, it enters a given critical section. When it is
  60. destroyed, it leaves the given critical section.
  61. CriticalSection a_cs;
  62. void blah() {
  63. InCriticalSection cs(a_cs); // critical section protection begins
  64. if (test) {
  65. return 0; // critical section protection ends
  66. }
  67. // critical section protection still active!
  68. doSomething();
  69. return 1; // critical section protection ends
  70. }
  71. @author Nullsoft
  72. @see CriticalSection
  73. */
  74. class InCriticalSection {
  75. public:
  76. InCriticalSection(CriticalSection *cs) : m_cs(cs) { m_cs->enter(); }
  77. InCriticalSection(CriticalSection &cs) : m_cs(&cs) { m_cs->enter(); }
  78. ~InCriticalSection() { m_cs->leave(); }
  79. private:
  80. CriticalSection *m_cs;
  81. };
  82. #define _INCRITICALSECTION(id, x) InCriticalSection __I_C_S__##id(x)
  83. #define INCRITICALSECTION(x) _INCRITICALSECTION(__LINE__, x)
  84. #endif