aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/critsec.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/critsec.h')
-rw-r--r--Src/Wasabi/bfc/critsec.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/critsec.h b/Src/Wasabi/bfc/critsec.h
new file mode 100644
index 00000000..e9951a9a
--- /dev/null
+++ b/Src/Wasabi/bfc/critsec.h
@@ -0,0 +1,96 @@
+#ifndef _CRITSEC_H
+#define _CRITSEC_H
+
+#ifdef _WIN32
+#include <windows.h>
+#elif defined(__APPLE__)
+#include <CoreServices/CoreServices.h>
+#endif
+
+#include <bfc/common.h>
+#include <bfc/bfc_assert.h>
+
+/**
+ CriticalSection is a portable object that implements a critical section,
+ which is to say, it ensures that no two threads can be in that same
+ section of code at the same time. Usually you make them a global object
+ or allocate them with new and pass them to both threads.
+
+ @short Critical section class.
+ @author Nullsoft
+ @ver 1.0
+ @see Thread
+ @see InCriticalSection
+*/
+
+class CriticalSection {
+public:
+ CriticalSection();
+ virtual ~CriticalSection();
+
+/**
+ Enters the critical section. If another thread is already in the critical
+ section, the calling thread will be blocked until the other thread calls
+ leave().
+ @see leave()
+*/
+ void enter();
+/**
+ Leaves the critical section. If another thread is currently blocked on
+ this critical section, it will be unblocked. If multiple threads are blocking
+ only one will be unblocked.
+ @see enter()
+*/
+ void leave();
+
+/**
+ Calls enter() and leave() in quick succession. Useful to make sure that no
+ other thread is in the critical section (although another thread could
+ immediately re-enter)
+ @see enter()
+ @see leave()
+*/
+ void inout();
+
+private:
+#ifdef ASSERTS_ENABLED
+ int within;
+#endif
+#ifdef _WIN32
+ CRITICAL_SECTION cs;
+#elif defined(__APPLE__)
+ MPCriticalRegionID cr;
+#endif
+
+};
+
+/**
+ This is a little helper class to ease the use of class CriticalSection.
+ When it is instantiated, it enters a given critical section. When it is
+ destroyed, it leaves the given critical section.
+ CriticalSection a_cs;
+ void blah() {
+ InCriticalSection cs(a_cs); // critical section protection begins
+ if (test) {
+ return 0; // critical section protection ends
+ }
+ // critical section protection still active!
+ doSomething();
+ return 1; // critical section protection ends
+ }
+
+ @author Nullsoft
+ @see CriticalSection
+*/
+class InCriticalSection {
+public:
+ InCriticalSection(CriticalSection *cs) : m_cs(cs) { m_cs->enter(); }
+ InCriticalSection(CriticalSection &cs) : m_cs(&cs) { m_cs->enter(); }
+ ~InCriticalSection() { m_cs->leave(); }
+private:
+ CriticalSection *m_cs;
+};
+
+#define _INCRITICALSECTION(id, x) InCriticalSection __I_C_S__##id(x)
+#define INCRITICALSECTION(x) _INCRITICALSECTION(__LINE__, x)
+#endif