Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* @file threads.hpp
* @copyright Copyright (c) 2020 University of Turku, MIT License
* @author Nicolas Pope
*/
#pragma once
#include <mutex>
#include <shared_mutex>
#include <ftl/lib/ctpl_stl.hpp>
#define POOL_SIZE 10
//#define DEBUG_MUTEX
#define MUTEX_TIMEOUT 2
#if defined DEBUG_MUTEX
#include <ftl/lib/loguru.hpp>
#include <chrono>
#include <type_traits>
#define MUTEX std::timed_mutex
#define RECURSIVE_MUTEX std::recursive_timed_mutex
#define SHARED_MUTEX std::shared_timed_mutex
#define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::milliseconds(MUTEX_TIMEOUT)); while (!L) { LOG(ERROR) << "Mutex timeout"; L.try_lock_for(std::chrono::milliseconds(MUTEX_TIMEOUT)); };
#define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::milliseconds(MUTEX_TIMEOUT)); while (!L) { LOG(ERROR) << "Mutex timeout"; L.try_lock_for(std::chrono::milliseconds(MUTEX_TIMEOUT)); };
#else
#define MUTEX std::mutex
#define RECURSIVE_MUTEX std::recursive_mutex
#define SHARED_MUTEX std::shared_mutex
#define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M);
#define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M);
#endif // DEBUG_MUTEX
#define SHARED_LOCK_TYPE(M) std::shared_lock<M>
namespace ftl {
extern ctpl::thread_pool pool;
namespace threads {
/** Upgrade shared lock to exclusive lock and re-acquire shared lock at end of
* scope. */
class _write_lock {
public:
explicit _write_lock(std::shared_mutex& mtx) : mtx_(&mtx) {
mtx_->unlock_shared();
mtx_->lock();
}
~_write_lock() {
mtx_->unlock();
mtx_->lock_shared();
}
private:
std::shared_mutex* const mtx_;
};
/** Upgrade already acquired SHARED_LOCK to exclusive lock and re-acquire shared
* lock at end of scope. Shared lock must be already acquired on mutex! If more
* careful locking is required, use std::..._lock directly */
#define WRITE_LOCK(M,L) ftl::threads::_write_lock L(M);
}
}