diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-10-07 16:59:55 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-10-07 17:13:05 +0000 |
commit | 6166dd0e28ab21be14a7c5018958f394d8e779db (patch) | |
tree | 9f1ebb0f4920ad377fda2b0de44a4a45d7ec121a /vespalib | |
parent | d8365f1cde0c00a5a671f87c0baad461beff28c2 (diff) |
Remove broken copy and move constructor and assignment operatoos on vespalib::Lock and vespalib::Monitor.
Also repair broken usages of the same.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/tests/sync/sync_test.cpp | 12 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/data/slime/json_format.cpp | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/testkit/test_hook.h | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/testkit/test_master.cpp | 3 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/alloc.cpp | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/child_process.cpp | 11 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/rwlock.cpp | 19 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/rwlock.h | 22 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp | 3 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/simple_thread_bundle.h | 2 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/sync.cpp | 153 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/sync.h | 176 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/thread.cpp | 1 |
14 files changed, 236 insertions, 170 deletions
diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp index a17f9089877..c8888bc8e54 100644 --- a/vespalib/src/tests/sync/sync_test.cpp +++ b/vespalib/src/tests/sync/sync_test.cpp @@ -119,17 +119,7 @@ Test::Main() CHECK_UNLOCKED(monitor); } } - // copy/assign is nop, but legal - { - Lock a; - Lock b(a); - b = a; - } - { - Monitor a; - Monitor b(a); - b = a; - } + // you can lock const objects { const Lock lock; diff --git a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp index d2f953b38c8..080e3b8da48 100644 --- a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp +++ b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp @@ -8,6 +8,7 @@ #include <vespa/vespalib/locale/c.h> #include <cmath> #include <sstream> +#include <cassert> #include <vespa/log/log.h> LOG_SETUP(".vespalib.data.slime.json_format"); diff --git a/vespalib/src/vespa/vespalib/testkit/test_hook.h b/vespalib/src/vespa/vespalib/testkit/test_hook.h index 28419c0b31b..706a1c9f741 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_hook.h +++ b/vespalib/src/vespa/vespalib/testkit/test_hook.h @@ -6,6 +6,7 @@ #include <vespa/vespalib/util/barrier.h> #include <string> #include <vector> +#include <cassert> #include "test_master.h" namespace vespalib { diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.cpp b/vespalib/src/vespa/vespalib/testkit/test_master.cpp index 789d40d478d..4b673d0ee0d 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_master.cpp +++ b/vespalib/src/vespa/vespalib/testkit/test_master.cpp @@ -3,6 +3,7 @@ #include "test_master.h" #include <vespa/vespalib/util/barrier.h> #include <cstring> +#include <cassert> #include <vespa/log/log.h> LOG_SETUP(".vespalib.testkit.test_master"); @@ -33,7 +34,7 @@ __thread TestMaster::ThreadState *TestMaster::_threadState = 0; //----------------------------------------------------------------------------- -TestMaster::TraceItem::~TraceItem() { } +TestMaster::TraceItem::~TraceItem() = default; TestMaster::ThreadState & TestMaster::threadState(const vespalib::LockGuard &) diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt index 0973653861f..fd645f9008c 100644 --- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt @@ -50,6 +50,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT stash.cpp string_hash.cpp stringfmt.cpp + sync.cpp thread.cpp thread_bundle.cpp threadstackexecutor.cpp diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp index 1303e7ffdee..5ae499f5482 100644 --- a/vespalib/src/vespa/vespalib/util/alloc.cpp +++ b/vespalib/src/vespa/vespalib/util/alloc.cpp @@ -8,6 +8,7 @@ #include <map> #include <atomic> #include <unordered_map> +#include <cassert> #include <vespa/fastos/file.h> #include <unistd.h> diff --git a/vespalib/src/vespa/vespalib/util/child_process.cpp b/vespalib/src/vespa/vespalib/util/child_process.cpp index ce0c2eb1779..b804d4ca87c 100644 --- a/vespalib/src/vespa/vespalib/util/child_process.cpp +++ b/vespalib/src/vespa/vespalib/util/child_process.cpp @@ -56,9 +56,6 @@ public: } // namespace child_process -using child_process::Timer; - -//----------------------------------------------------------------------------- void ChildProcess::Reader::OnReceiveData(const void *data, size_t length) @@ -88,7 +85,7 @@ ChildProcess::Reader::hasData() bool -ChildProcess::Reader::waitForData(Timer &timer, MonitorGuard &lock) +ChildProcess::Reader::waitForData(child_process::Timer &timer, MonitorGuard &lock) { // NB: caller has lock on _cond CounterGuard count(_waitCnt); @@ -131,7 +128,7 @@ ChildProcess::Reader::read(char *buf, uint32_t len, int msTimeout) if (eof()) { return 0; } - Timer timer(msTimeout); + child_process::Timer timer(msTimeout); MonitorGuard lock(_cond); waitForData(timer, lock); uint32_t bytes = 0; @@ -162,7 +159,7 @@ ChildProcess::Reader::readLine(std::string &line, int msTimeout) if (eof()) { return false; } - Timer timer(msTimeout); + child_process::Timer timer(msTimeout); MonitorGuard lock(_cond); while (waitForData(timer, lock)) { while (hasData()) { @@ -299,7 +296,7 @@ ChildProcess::run(const std::string &input, const char *cmd, std::string &output, int msTimeout) { ChildProcess proc(cmd); - Timer timer(msTimeout); + child_process::Timer timer(msTimeout); char buf[4096]; proc.write(input.data(), input.length()); proc.close(); // close stdin diff --git a/vespalib/src/vespa/vespalib/util/rwlock.cpp b/vespalib/src/vespa/vespalib/util/rwlock.cpp index d1e155851cf..fc3799bc1d0 100644 --- a/vespalib/src/vespa/vespalib/util/rwlock.cpp +++ b/vespalib/src/vespa/vespalib/util/rwlock.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vespalib/util/rwlock.h> +#include "rwlock.h" +#include <cassert> namespace vespalib { @@ -39,4 +40,20 @@ void RWLock::unlockWrite() { } } +RWLock * +RWLockReader::stealLock() { + RWLock * ret(_lock); + assert(ret != nullptr); + _lock = nullptr; + return ret; +} + +RWLock * +RWLockWriter::stealLock() { + RWLock * ret(_lock); + assert(ret != nullptr); + _lock = nullptr; + return ret; +} + } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/util/rwlock.h b/vespalib/src/vespa/vespalib/util/rwlock.h index 9b1f9b93289..8818291ae6c 100644 --- a/vespalib/src/vespa/vespalib/util/rwlock.h +++ b/vespalib/src/vespa/vespalib/util/rwlock.h @@ -119,13 +119,8 @@ class RWLockReader { private: RWLock * _lock; - RWLock * stealLock() { - RWLock * ret(_lock); - assert(ret != NULL); - _lock = NULL; - return ret; - } - void cleanup() { if (_lock != NULL) { _lock->unlockRead(); } } + RWLock * stealLock(); + void cleanup() { if (_lock != nullptr) { _lock->unlockRead(); } } public: /** @@ -141,7 +136,7 @@ public: * @brief Construct initially unlocked guard. * @param tag (unused) marker argument **/ - RWLockReader(const RWLock::InitiallyUnlockedGuard &tag) : _lock(NULL) { (void)tag; } + RWLockReader(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; } /** * @brief Steal the lock from the given RWLockReader @@ -191,13 +186,8 @@ class RWLockWriter { private: RWLock * _lock; - RWLock * stealLock() { - RWLock * ret(_lock); - assert(ret != NULL); - _lock = NULL; - return ret; - } - void cleanup() { if (_lock != NULL) { _lock->unlockWrite(); } } + RWLock * stealLock(); + void cleanup() { if (_lock != nullptr) { _lock->unlockWrite(); } } public: /** @@ -213,7 +203,7 @@ public: * @brief Construct initially unlocked guard. * @param tag (unused) marker argument **/ - RWLockWriter(const RWLock::InitiallyUnlockedGuard &tag) : _lock(NULL) { (void)tag; } + RWLockWriter(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; } /** * @brief Steal the lock from the given RWLockWriter diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp index 01979c25164..886003a2ab6 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp @@ -2,6 +2,7 @@ #include "simple_thread_bundle.h" #include "exceptions.h" +#include <cassert> using namespace vespalib::fixed_thread_bundle; @@ -75,7 +76,7 @@ SimpleThreadBundle::Pool::obtain() return ret; } } - return SimpleThreadBundle::UP(new SimpleThreadBundle(_bundleSize)); + return std::make_unique<SimpleThreadBundle>(_bundleSize); } void diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h index 4fa73c1112f..dbf9f7025b6 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h @@ -48,7 +48,7 @@ struct Signal { bool valid; size_t generation; Monitor monitor; - Signal() : valid(true), generation(0), monitor() {} + Signal() noexcept : valid(true), generation(0), monitor() {} size_t wait(size_t &localGen) { MonitorGuard guard(monitor); while (localGen == generation) { diff --git a/vespalib/src/vespa/vespalib/util/sync.cpp b/vespalib/src/vespa/vespalib/util/sync.cpp new file mode 100644 index 00000000000..3819b2b3369 --- /dev/null +++ b/vespalib/src/vespa/vespalib/util/sync.cpp @@ -0,0 +1,153 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "sync.h" +#include <cassert> + +namespace vespalib { + +Lock::Lock() noexcept + : _mutex(std::make_unique<std::mutex>()) +{} +Lock::Lock(Lock &&rhs) noexcept = default; +Lock::~Lock() = default; + + +Monitor::Monitor() noexcept + : Lock(), + _cond(std::make_unique<std::condition_variable>()) +{} +Monitor::Monitor(Monitor &&rhs) noexcept = default; +Monitor::~Monitor() = default; + + +TryLock::TryLock(const Lock &lock) + : _guard(*lock._mutex, std::try_to_lock), + _cond(nullptr) +{} + +TryLock::TryLock(const Monitor &mon) + : _guard(*mon._mutex, std::try_to_lock), + _cond(_guard ? mon._cond.get() : nullptr) +{} + +TryLock::TryLock(TryLock &&rhs) noexcept + : _guard(std::move(rhs._guard)), + _cond(rhs._cond) +{ + rhs._cond = nullptr; +} + +TryLock::~TryLock() = default; + +bool +TryLock::hasLock() const { + return static_cast<bool>(_guard); +} + +void +TryLock::unlock() { + if (_guard) { + _guard.unlock(); + _cond = nullptr; + } +} + +LockGuard::LockGuard() : _guard() {} + +LockGuard::LockGuard(LockGuard &&rhs) noexcept : _guard(std::move(rhs._guard)) { } +LockGuard::LockGuard(const Lock &lock) : _guard(*lock._mutex) { } +LockGuard::LockGuard(TryLock &&tlock) : _guard(std::move(tlock._guard)) +{ + tlock._cond = nullptr; +} + +LockGuard & +LockGuard::operator=(LockGuard &&rhs) noexcept{ + if (this != &rhs) { + _guard = std::move(rhs._guard); + } + return *this; +} + +void +LockGuard::unlock() { + if (_guard) { + _guard.unlock(); + } +} +LockGuard::~LockGuard() = default; + +bool +LockGuard::locks(const Lock& lock) const { + return (_guard && _guard.mutex() == lock._mutex.get()); +} + +MonitorGuard::MonitorGuard() : _guard(), _cond(nullptr) {} +MonitorGuard::MonitorGuard(MonitorGuard &&rhs) noexcept + : _guard(std::move(rhs._guard)), + _cond(rhs._cond) +{ + rhs._cond = nullptr; +} +MonitorGuard::MonitorGuard(const Monitor &monitor) + : _guard(*monitor._mutex), + _cond(monitor._cond.get()) +{ } +MonitorGuard::MonitorGuard(TryLock &&tlock) + : _guard(), + _cond(nullptr) +{ + if (tlock._guard && tlock._cond != nullptr) { + _guard = std::move(tlock._guard); + _cond = tlock._cond; + tlock._cond = nullptr; + } +} + +MonitorGuard & +MonitorGuard::operator=(MonitorGuard &&rhs) noexcept { + if (this != &rhs) { + _guard = std::move(rhs._guard); + _cond = rhs._cond; + rhs._cond = nullptr; + } + return *this; +} + +void +MonitorGuard::unlock() { + assert(_guard); + _guard.unlock(); + _cond = nullptr; +} +void +MonitorGuard::wait() { + _cond->wait(_guard); +} +bool +MonitorGuard::wait(int msTimeout) { + return wait(std::chrono::milliseconds(msTimeout)); +} +bool +MonitorGuard::wait(std::chrono::nanoseconds timeout) { + return _cond->wait_for(_guard, timeout) == std::cv_status::no_timeout; +} +void +MonitorGuard::signal() { + _cond->notify_one(); +} +void +MonitorGuard::broadcast() { + _cond->notify_all(); +} +void +MonitorGuard::unsafeSignalUnlock() { + _guard.unlock(); + _cond->notify_one(); + _cond = nullptr; +} + +MonitorGuard::~MonitorGuard() = default; + +} // namespace vespalib + diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h index 043bb477c89..b1227ce658e 100644 --- a/vespalib/src/vespa/vespalib/util/sync.h +++ b/vespalib/src/vespa/vespalib/util/sync.h @@ -2,10 +2,9 @@ #pragma once -#include <cassert> +#include "time.h" #include <mutex> #include <condition_variable> -#include <chrono> namespace vespalib { @@ -25,19 +24,16 @@ protected: friend class LockGuard; friend class TryLock; - mutable std::mutex _mutex; + std::unique_ptr<std::mutex> _mutex; public: /** * @brief Create a new Lock. * * Creates a Lock that has mutex instrumentation disabled. **/ - Lock() noexcept : _mutex() {} - //TODO Remove The below methods are very bad and have a dodgy history. - Lock(const Lock &) : Lock() { } - Lock(Lock &&) noexcept : Lock() { } - Lock &operator=(const Lock &) { return *this; } - Lock &operator=(Lock &&) { return *this; } + Lock() noexcept; + Lock(Lock && rhs) noexcept; + ~Lock(); }; @@ -60,19 +56,16 @@ private: friend class MonitorGuard; friend class TryLock; - mutable std::condition_variable _cond; + std::unique_ptr<std::condition_variable> _cond; public: /** * @brief Create a new Monitor. * * Creates a Monitor that has mutex instrumentation disabled. **/ - Monitor() noexcept : Lock(), _cond() {} - //TODO Remove The below methods are very bad and have a dodgy history. - Monitor(const Monitor &) : Monitor() { } - Monitor(Monitor &&) noexcept : Monitor() { } - Monitor &operator=(const Monitor &) { return *this; } - Monitor &operator=(Monitor &&) { return *this; } + Monitor() noexcept; + Monitor(Monitor && rhs) noexcept; + ~Monitor(); }; @@ -114,59 +107,39 @@ private: std::unique_lock<std::mutex> _guard; std::condition_variable *_cond; - TryLock(const TryLock &) = delete; - TryLock &operator=(const TryLock &) = delete; - public: /** * @brief Try to obtain the lock represented by the given Lock object * * @param lock the lock to obtain **/ - TryLock(const Lock &lock) - : _guard(lock._mutex, std::try_to_lock), - _cond(nullptr) - { - } + TryLock(const Lock &lock); /** * @brief Try to lock the given Monitor * * @param mon the monitor to lock **/ - TryLock(const Monitor &mon) - : _guard(mon._mutex, std::try_to_lock), - _cond(_guard ? &mon._cond : nullptr) - { - } + TryLock(const Monitor &mon); - TryLock(TryLock &&rhs) - : _guard(std::move(rhs._guard)), - _cond(rhs._cond) - { - rhs._cond = nullptr; - } + TryLock(TryLock &&rhs) noexcept; /** * @brief Release the lock held by this object, if any **/ - ~TryLock() = default; - - TryLock &operator=(TryLock &&rhs) { - if (this != &rhs) { - _guard = std::move(rhs._guard); - _cond = rhs._cond; - rhs._cond = nullptr; - } - return *this; - } + ~TryLock(); + + TryLock(const TryLock &) = delete; + TryLock &operator=(const TryLock &) = delete; + + TryLock &operator=(TryLock &&rhs) noexcept; /** * @brief Check whether this object holds a lock * * @return true if this object holds a lock **/ - bool hasLock() { return static_cast<bool>(_guard); } + bool hasLock() const; /** * @brief Release the lock held by this object. * @@ -175,12 +148,7 @@ public: * need to release the lock before the object is destructed, as * the destructor will release the lock. **/ - void unlock() { - if (_guard) { - _guard.unlock(); - _cond = nullptr; - } - } + void unlock(); }; @@ -200,19 +168,20 @@ class LockGuard { private: std::unique_lock<std::mutex> _guard; - LockGuard &operator=(const LockGuard &) = delete; public: /** * @brief A noop guard without any mutex. **/ - LockGuard() : _guard() {} + LockGuard(); LockGuard(const LockGuard &rhs) = delete; + LockGuard &operator=(const LockGuard &) = delete; + /** * @brief Steal the lock from the given LockGuard * * @param rhs steal the lock from this one **/ - LockGuard(LockGuard &&rhs) : _guard(std::move(rhs._guard)) { } + LockGuard(LockGuard &&rhs) noexcept; /** * @brief Obtain the lock represented by the given Lock object. * @@ -220,7 +189,7 @@ public: * * @param lock take it **/ - LockGuard(const Lock &lock) : _guard(lock._mutex) { } + LockGuard(const Lock &lock); /** * @brief Create a LockGuard from a TryLock. @@ -231,17 +200,9 @@ public: * * @param tlock take the lock from this one **/ - LockGuard(TryLock &&tlock) : _guard(std::move(tlock._guard)) - { - tlock._cond = nullptr; - } + LockGuard(TryLock &&tlock); - LockGuard &operator=(LockGuard &&rhs) { - if (this != &rhs) { - _guard = std::move(rhs._guard); - } - return *this; - } + LockGuard &operator=(LockGuard &&rhs) noexcept; /** * @brief Release the lock held by this object. @@ -251,24 +212,18 @@ public: * need to release the lock before the object is destructed, as * the destructor will release the lock. **/ - void unlock() { - if (_guard) { - _guard.unlock(); - } - } + void unlock(); /** * @brief Release the lock held by this object if unlock has not * been called. **/ - ~LockGuard() = default; + ~LockGuard(); /** * Allow code to match guard with lock. This allows functions to take a * guard ref as input, ensuring that the caller have grabbed a lock. */ - bool locks(const Lock& lock) const { - return (_guard && _guard.mutex() == &lock._mutex); - } + bool locks(const Lock& lock) const; }; @@ -296,19 +251,14 @@ public: /** * @brief A noop guard without any condition. **/ - MonitorGuard() : _guard(), _cond(nullptr) {} + MonitorGuard(); MonitorGuard(const MonitorGuard &rhs) = delete; /** * @brief Steal the lock from the given MonitorGuard * * @param rhs steal the lock from this one **/ - MonitorGuard(MonitorGuard &&rhs) - : _guard(std::move(rhs._guard)), - _cond(rhs._cond) - { - rhs._cond = nullptr; - } + MonitorGuard(MonitorGuard &&rhs) noexcept; /** * @brief Obtain the lock on the given Monitor object. * @@ -316,11 +266,7 @@ public: * * @param monitor take the lock on it **/ - MonitorGuard(const Monitor &monitor) - : _guard(monitor._mutex), - _cond(&monitor._cond) - { - } + MonitorGuard(const Monitor &monitor); /** * @brief Create a MonitorGuard from a TryLock. * @@ -330,25 +276,9 @@ public: * * @param tlock take the lock from this one **/ - MonitorGuard(TryLock &&tlock) - : _guard(), - _cond(nullptr) - { - if (tlock._guard && tlock._cond != nullptr) { - _guard = std::move(tlock._guard); - _cond = tlock._cond; - tlock._cond = nullptr; - } - } + MonitorGuard(TryLock &&tlock); - MonitorGuard &operator=(MonitorGuard &&rhs) { - if (this != &rhs) { - _guard = std::move(rhs._guard); - _cond = rhs._cond; - rhs._cond = nullptr; - } - return *this; - } + MonitorGuard &operator=(MonitorGuard &&rhs) noexcept; /** @@ -359,17 +289,11 @@ public: * need to release the lock before this object is destructed, as * the destructor will release the lock. **/ - void unlock() { - assert(_guard); - _guard.unlock(); - _cond = nullptr; - } + void unlock(); /** * @brief Wait for a signal on the underlying Monitor. **/ - void wait() { - _cond->wait(_guard); - } + void wait(); /** * @brief Wait for a signal on the underlying Monitor with the * given timeout. @@ -377,25 +301,17 @@ public: * @param msTimeout timeout in milliseconds * @return true if a signal was received, false if the wait timed out. **/ - bool wait(int msTimeout) { - return wait(std::chrono::milliseconds(msTimeout)); - } - bool wait(std::chrono::nanoseconds timeout) { - return _cond->wait_for(_guard, timeout) == std::cv_status::no_timeout; - } + bool wait(int msTimeout); + bool wait(duration timeout); /** * @brief Send a signal to a single waiter on the underlying * Monitor. **/ - void signal() { - _cond->notify_one(); - } + void signal(); /** * @brief Send a signal to all waiters on the underlying Monitor. **/ - void broadcast() { - _cond->notify_all(); - } + void broadcast(); /** * @brief Send a signal to a single waiter on the underlying * Monitor, but unlock the monitor right before doing so. @@ -404,24 +320,20 @@ public: * synchronization to ensure that the underlying Monitor object * will live long enough to be signaled. **/ - void unsafeSignalUnlock() { - _guard.unlock(); - _cond->notify_one(); - _cond = nullptr; - } + void unsafeSignalUnlock(); /** * @brief Release the lock held by this object if unlock has not * been called. **/ - ~MonitorGuard() = default; + ~MonitorGuard(); /** * Allow code to match guard with lock. This allows functions to take a * guard ref as input, ensuring that the caller have grabbed a lock. */ bool monitors(const Monitor& m) const { - return (_cond != nullptr && _cond == &m._cond); + return (_cond != nullptr && _cond == m._cond.get()); } }; diff --git a/vespalib/src/vespa/vespalib/util/thread.cpp b/vespalib/src/vespa/vespalib/util/thread.cpp index 4eb436458a2..c595a76b8fe 100644 --- a/vespalib/src/vespa/vespalib/util/thread.cpp +++ b/vespalib/src/vespa/vespalib/util/thread.cpp @@ -2,6 +2,7 @@ #include "thread.h" #include <thread> +#include <cassert> namespace vespalib { |