summaryrefslogtreecommitdiffstats
path: root/ipc/chromium/src/mojo/core/ports/port.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/chromium/src/mojo/core/ports/port.h')
-rw-r--r--ipc/chromium/src/mojo/core/ports/port.h36
1 files changed, 35 insertions, 1 deletions
diff --git a/ipc/chromium/src/mojo/core/ports/port.h b/ipc/chromium/src/mojo/core/ports/port.h
index 44529ddb6f..78fe0109b8 100644
--- a/ipc/chromium/src/mojo/core/ports/port.h
+++ b/ipc/chromium/src/mojo/core/ports/port.h
@@ -18,6 +18,18 @@
#include "mozilla/RefPtr.h"
#include "nsISupportsImpl.h"
+#ifdef MOZ_TSAN
+// In TSAN builds, a single static mutex is used for all ports, rather than
+// per-port mutexes, to avoid overloading the maximum 64 concurrently-held locks
+// limit of its deadlock detector when sending messages with a large number of
+// attached ports.
+# define MOZ_USE_SINGLETON_PORT_MUTEX 1
+#endif
+
+#ifdef MOZ_USE_SINGLETON_PORT_MUTEX
+# include "mozilla/StaticMutex.h"
+#endif
+
namespace mojo {
namespace core {
namespace ports {
@@ -28,20 +40,38 @@ namespace detail {
// Ports cannot use mozilla::Mutex, as the acquires-before relationships handled
// by PortLocker can overload the debug-only deadlock detector.
-class MOZ_CAPABILITY("mutex") PortMutex : private ::mozilla::detail::MutexImpl {
+class MOZ_CAPABILITY("mutex") PortMutex
+#ifndef MOZ_USE_SINGLETON_PORT_MUTEX
+ : private ::mozilla::detail::MutexImpl
+#endif
+{
public:
void AssertCurrentThreadOwns() const MOZ_ASSERT_CAPABILITY(this) {
#ifdef DEBUG
MOZ_ASSERT(mOwningThread == PR_GetCurrentThread());
#endif
+#ifdef MOZ_USE_SINGLETON_PORT_MUTEX
+ sSingleton.AssertCurrentThreadOwns();
+#endif
}
private:
// PortMutex should only be locked/unlocked via PortLocker
friend class ::mojo::core::ports::PortLocker;
+#ifdef MOZ_USE_SINGLETON_PORT_MUTEX
+ // If the singleton mutex is in use, it must be locked before calling `Lock()`
+ // on any port, and must only be unlocked after calling `Unlock()` on every
+ // locked port.
+ static ::mozilla::StaticMutex sSingleton;
+#endif
+
void Lock() MOZ_CAPABILITY_ACQUIRE() {
+#ifdef MOZ_USE_SINGLETON_PORT_MUTEX
+ sSingleton.AssertCurrentThreadOwns();
+#else
::mozilla::detail::MutexImpl::lock();
+#endif
#ifdef DEBUG
mOwningThread = PR_GetCurrentThread();
#endif
@@ -51,7 +81,11 @@ class MOZ_CAPABILITY("mutex") PortMutex : private ::mozilla::detail::MutexImpl {
MOZ_ASSERT(mOwningThread == PR_GetCurrentThread());
mOwningThread = nullptr;
#endif
+#ifdef MOZ_USE_SINGLETON_PORT_MUTEX
+ sSingleton.AssertCurrentThreadOwns();
+#else
::mozilla::detail::MutexImpl::unlock();
+#endif
}
#ifdef DEBUG