diff options
Diffstat (limited to 'ipc/chromium/src/mojo/core/ports/port.h')
-rw-r--r-- | ipc/chromium/src/mojo/core/ports/port.h | 36 |
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 |