summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-10-07 16:59:55 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-10-07 17:13:05 +0000
commit6166dd0e28ab21be14a7c5018958f394d8e779db (patch)
tree9f1ebb0f4920ad377fda2b0de44a4a45d7ec121a /vespalib
parentd8365f1cde0c00a5a671f87c0baad461beff28c2 (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.cpp12
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/json_format.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_hook.h1
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.cpp3
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/util/child_process.cpp11
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.cpp19
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.h22
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp3
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.h2
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.cpp153
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.h176
-rw-r--r--vespalib/src/vespa/vespalib/util/thread.cpp1
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 {