8000 Feature/guarded mutex by goedderz · Pull Request #13996 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content

Feature/guarded mutex #13996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
333d579
Began work on a value guarded by mutex implementation
goedderz Jul 9, 2019
4657757
Added (empty) test file
goedderz Jul 18, 2019
86ff2c1
A first test, and some fixes
goedderz Oct 9, 2019
08adbf4
Deleted copy&move constructors
goedderz Oct 10, 2019
ea01ee2
explicitly defaulted destructor
goedderz Oct 10, 2019
4326973
Switched to trailing return types
goedderz Oct 2, 2020
b8c7f3d
Some improvements and more tests
goedderz Nov 13, 2020
4c07156
Rename arangodb::Mutex::tryLock to make Mutex more compatible with st…
goedderz Nov 19, 2020
612aee7
Moved Guarded files to Basics
goedderz Nov 19, 2020
d691764
minor cleanup
goedderz Nov 19, 2020
1eec096
added comment
goedderz Nov 19, 2020
6ea04cc
parametrized lock
goedderz Nov 19, 2020
f01691e
added test assertions
goedderz Nov 20, 2020
a4e1735
Fixed windows, added a test
goedderz Nov 20, 2020
2d843dc
Added assign and copy
goedderz Nov 20, 2020
3971e76
Merge branch 'devel' of github.com:arangodb/arangodb into feature/gua…
goedderz Apr 16, 2021
09aa867
Add perfect forwarding in Guarded constructor
goedderz Apr 29, 2021
c206171 8000
Merge branch 'devel' of github.com:arangodb/arangodb into feature/gua…
goedderz Jun 1, 2021
1561c4f
Backported some changes from replication-2.0
goedderz Jun 1, 2021
add04ec
Merge branch 'devel' of github.com:arangodb/arangodb into feature/gua…
goedderz Jun 29, 2021
c6668d3
Minor changes
goedderz Jun 29, 2021
ea89666
Added missing tests
goedderz Jun 29, 2021
52b76b3
Minor changes from review
goedderz Jul 9, 2021
d0ebb4c
Remove code duplication as suggested in the review
goedderz Jul 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
A first test, and some fixes
  • Loading branch information
goedderz committed Oct 2, 2020
commit 86ff2c1b26e3b614b08a731422b8b82be2758800
46 changes: 29 additions & 17 deletions lib/Utilities/Guarded.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Mutex;
template <class T, class M = Mutex>
class MutexGuard {
public:
explicit MutexGuard(T& value, M mutex);
explicit MutexGuard(T& value, M& mutex);
~MutexGuard();

T& get() noexcept;
Expand All @@ -47,7 +47,7 @@ class MutexGuard {
};

template <class T, class M>
MutexGuard<T, M>::MutexGuard(T& value, M mutex) : _value(value), _mutex(mutex) {
MutexGuard<T, M>::MutexGuard(T& value, M& mutex) : _value(value), _mutex(mutex) {
_mutex.lock();
}

Expand All @@ -69,14 +69,18 @@ T const& MutexGuard<T, M>::get() const noexcept {
template <class T, class M = Mutex>
class Guarded {
public:
explicit Guarded(T&& value = T(), M&& mutex = M());
explicit Guarded(T value = T(), M mutex = M());
explicit Guarded(T&& value = T());
template <typename... Args>
explicit Guarded(Args...);

// TODO with C++17, these could be noexcept depending on callback being noexcept
template <class F>
decltype(F()) doUnderLock(F callback);
std::result_of_t<F(T&)> doUnderLock(F callback);
template <class F>
decltype(F(false)) tryUnderLock(F callback);
std::result_of_t<F(T const&)> doUnderLock(F callback);

// template <class F>
// decltype(F(false)) tryUnderLock(F callback);
// TODO add more types of "do under lock"?

MutexGuard<T, M> getLockedGuard();
Expand All @@ -88,31 +92,39 @@ class Guarded {
};

template <class T, class M>
Guarded<T, M>::Guarded(T&& value, M&& mutex)
: _value(std::forward<T>(value)), _mutex(std::forward<T>(mutex)) {}
Guarded<T, M>::Guarded(T&& value) : _value{std::move(value)}, _mutex{} {}

template <class T, class M>
Guarded<T, M>::Guarded(T value, M mutex)
: _value(std::move(value)), _mutex(std::move(mutex)) {}
template <typename... Args>
Guarded<T, M>::Guarded(Args... args) : _value{args...}, _mutex{} {}

template <class T, class M>
template <class F>
decltype(F()) Guarded<T, M>::doUnderLock(F callback) {
std::result_of_t<F(T&)> Guarded<T, M>::doUnderLock(F callback) {
MUTEX_LOCKER(guard, _mutex);

return callback();
return callback(_value);
}

template <class T, class M>
template <class F>
decltype(F(false)) Guarded<T, M>::tryUnderLock(F callback) {
TRY_MUTEX_LOCKER(guard, _mutex);
std::result_of_t<F(T const&)> Guarded<T, M>::doUnderLock(F callback) {
MUTEX_LOCKER(guard, _mutex);

return callback(guard.isLocked());
return callback(_value);
}

// template <class T, class M>
// template <class F>
// decltype(F(false)) Guarded<T, M>::tryUnderLock(F callback) {
// TRY_MUTEX_LOCKER(guard, _mutex);
//
// return callback(guard.isLocked());
// }

template <class T, class M>
MutexGuard Guarded<T, M>::getLockedGuard() {
return MutexGuard(_value, _mutex);
MutexGuard<T, M> Guarded<T, M>::getLockedGuard() {
return MutexGuard<T, M>(_value, _mutex);
}

} // namespace arangodb
Expand Down
48 changes: 46 additions & 2 deletions tests/Basics/GuardedTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,52 @@

#include "gtest/gtest.h"

#include <lib/Utilities/Guarded.h>
#include "Utilities/Guarded.h"
#include "Basics/Mutex.h"

TEST(GuardedTest, basics) {
#include <mutex>

using namespace arangodb;

namespace arangodb {
namespace tests {

template <typename Mutex>
class GuardedTest : public ::testing::Test {
};

TYPED_TEST_CASE_P(GuardedTest);

TYPED_TEST_P(GuardedTest, test_allows_access) {
struct UnderGuard {
int val{};
};
Guarded<UnderGuard, Mutex> guardedObj{UnderGuard{.val = 1}};
{
MutexGuard<UnderGuard, Mutex> guard = guardedObj.getLockedGuard();
EXPECT_EQ(1, guard.get().val);
guard.get().val = 2;
EXPECT_EQ(2, guard.get().val);
}
guardedObj.doUnderLock([](UnderGuard& obj) {
EXPECT_EQ(2, obj.val);
obj.val = 3;
EXPECT_EQ(3, obj.val);
});
// guardedObj.tryUnderLock([](UnderGuard& obj) { ... });
{
MutexGuard<UnderGuard, Mutex> guard = guardedObj.getLockedGuard();
EXPECT_EQ(3, guard.get().val);
}
}

TYPED_TEST_P(GuardedTest, test_2) {}

REGISTER_TYPED_TEST_CASE_P(GuardedTest, test_allows_access, test_2);

using TestedMutexes = ::testing::Types<std::mutex, arangodb::Mutex>;

INSTANTIATE_TYPED_TEST_CASE_P(GuardedTestInstantiation, GuardedTest, TestedMutexes);

} // namespace tests
} // namespace arangodb
0