summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/base/criticalsection.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/webrtc/base/criticalsection.h')
-rw-r--r--chromium/third_party/webrtc/base/criticalsection.h179
1 files changed, 179 insertions, 0 deletions
diff --git a/chromium/third_party/webrtc/base/criticalsection.h b/chromium/third_party/webrtc/base/criticalsection.h
new file mode 100644
index 00000000000..a950a47f592
--- /dev/null
+++ b/chromium/third_party/webrtc/base/criticalsection.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_BASE_CRITICALSECTION_H__
+#define WEBRTC_BASE_CRITICALSECTION_H__
+
+#include "webrtc/base/constructormagic.h"
+
+#if defined(WEBRTC_WIN)
+#include "webrtc/base/win32.h"
+#endif
+
+#if defined(WEBRTC_POSIX)
+#include <pthread.h>
+#endif
+
+#ifdef _DEBUG
+#define CS_TRACK_OWNER 1
+#endif // _DEBUG
+
+#if CS_TRACK_OWNER
+#define TRACK_OWNER(x) x
+#else // !CS_TRACK_OWNER
+#define TRACK_OWNER(x)
+#endif // !CS_TRACK_OWNER
+
+namespace rtc {
+
+#if defined(WEBRTC_WIN)
+class CriticalSection {
+ public:
+ CriticalSection() {
+ InitializeCriticalSection(&crit_);
+ // Windows docs say 0 is not a valid thread id
+ TRACK_OWNER(thread_ = 0);
+ }
+ ~CriticalSection() {
+ DeleteCriticalSection(&crit_);
+ }
+ void Enter() {
+ EnterCriticalSection(&crit_);
+ TRACK_OWNER(thread_ = GetCurrentThreadId());
+ }
+ bool TryEnter() {
+ if (TryEnterCriticalSection(&crit_) != FALSE) {
+ TRACK_OWNER(thread_ = GetCurrentThreadId());
+ return true;
+ }
+ return false;
+ }
+ void Leave() {
+ TRACK_OWNER(thread_ = 0);
+ LeaveCriticalSection(&crit_);
+ }
+
+#if CS_TRACK_OWNER
+ bool CurrentThreadIsOwner() const { return thread_ == GetCurrentThreadId(); }
+#endif // CS_TRACK_OWNER
+
+ private:
+ CRITICAL_SECTION crit_;
+ TRACK_OWNER(DWORD thread_); // The section's owning thread id
+};
+#endif // WEBRTC_WIN
+
+#if defined(WEBRTC_POSIX)
+class CriticalSection {
+ public:
+ CriticalSection() {
+ pthread_mutexattr_t mutex_attribute;
+ pthread_mutexattr_init(&mutex_attribute);
+ pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mutex_, &mutex_attribute);
+ pthread_mutexattr_destroy(&mutex_attribute);
+ TRACK_OWNER(thread_ = 0);
+ }
+ ~CriticalSection() {
+ pthread_mutex_destroy(&mutex_);
+ }
+ void Enter() {
+ pthread_mutex_lock(&mutex_);
+ TRACK_OWNER(thread_ = pthread_self());
+ }
+ bool TryEnter() {
+ if (pthread_mutex_trylock(&mutex_) == 0) {
+ TRACK_OWNER(thread_ = pthread_self());
+ return true;
+ }
+ return false;
+ }
+ void Leave() {
+ TRACK_OWNER(thread_ = 0);
+ pthread_mutex_unlock(&mutex_);
+ }
+
+#if CS_TRACK_OWNER
+ bool CurrentThreadIsOwner() const { return pthread_equal(thread_, pthread_self()); }
+#endif // CS_TRACK_OWNER
+
+ private:
+ pthread_mutex_t mutex_;
+ TRACK_OWNER(pthread_t thread_);
+};
+#endif // WEBRTC_POSIX
+
+// CritScope, for serializing execution through a scope.
+class CritScope {
+ public:
+ explicit CritScope(CriticalSection *pcrit) {
+ pcrit_ = pcrit;
+ pcrit_->Enter();
+ }
+ ~CritScope() {
+ pcrit_->Leave();
+ }
+ private:
+ CriticalSection *pcrit_;
+ DISALLOW_COPY_AND_ASSIGN(CritScope);
+};
+
+// Tries to lock a critical section on construction via
+// CriticalSection::TryEnter, and unlocks on destruction if the
+// lock was taken. Never blocks.
+//
+// IMPORTANT: Unlike CritScope, the lock may not be owned by this thread in
+// subsequent code. Users *must* check locked() to determine if the
+// lock was taken. If you're not calling locked(), you're doing it wrong!
+class TryCritScope {
+ public:
+ explicit TryCritScope(CriticalSection *pcrit) {
+ pcrit_ = pcrit;
+ locked_ = pcrit_->TryEnter();
+ }
+ ~TryCritScope() {
+ if (locked_) {
+ pcrit_->Leave();
+ }
+ }
+ bool locked() const {
+ return locked_;
+ }
+ private:
+ CriticalSection *pcrit_;
+ bool locked_;
+ DISALLOW_COPY_AND_ASSIGN(TryCritScope);
+};
+
+// TODO: Move this to atomicops.h, which can't be done easily because of
+// complex compile rules.
+class AtomicOps {
+ public:
+#if defined(WEBRTC_WIN)
+ // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
+ static int Increment(int* i) {
+ return ::InterlockedIncrement(reinterpret_cast<LONG*>(i));
+ }
+ static int Decrement(int* i) {
+ return ::InterlockedDecrement(reinterpret_cast<LONG*>(i));
+ }
+#else
+ static int Increment(int* i) {
+ return __sync_add_and_fetch(i, 1);
+ }
+ static int Decrement(int* i) {
+ return __sync_sub_and_fetch(i, 1);
+ }
+#endif
+};
+
+} // namespace rtc
+
+#endif // WEBRTC_BASE_CRITICALSECTION_H__