lokinet/llarp/util/threading.hpp

89 lines
1.6 KiB
C++
Raw Normal View History

#ifndef LLARP_THREADING_HPP
#define LLARP_THREADING_HPP
#include <absl/synchronization/barrier.h>
#include <absl/synchronization/mutex.h>
#include <absl/time/time.h>
2018-08-12 17:22:29 +00:00
namespace llarp
{
namespace util
{
/// a mutex that does nothing
struct LOCKABLE NullMutex
2018-08-12 17:22:29 +00:00
{
};
/// a lock that does nothing
struct SCOPED_LOCKABLE NullLock
2018-08-12 17:22:29 +00:00
{
NullLock(__attribute__((unused)) const NullMutex* mtx)
EXCLUSIVE_LOCK_FUNCTION(mtx)
{
}
~NullLock() UNLOCK_FUNCTION()
2018-08-12 17:22:29 +00:00
{
}
};
using Mutex = absl::Mutex;
using Lock = absl::MutexLock;
using Condition = absl::CondVar;
2018-08-12 17:22:29 +00:00
2018-11-17 21:07:04 +00:00
class Semaphore
{
private:
Mutex m_mutex; // protects m_count
size_t m_count GUARDED_BY(m_mutex);
bool
ready() const SHARED_LOCKS_REQUIRED(m_mutex)
{
return m_count > 0;
}
2018-11-17 21:07:04 +00:00
public:
Semaphore(size_t count) : m_count(count)
{
}
void
notify() LOCKS_EXCLUDED(m_mutex)
2018-11-17 21:07:04 +00:00
{
Lock lock(&m_mutex);
2018-11-17 21:07:04 +00:00
m_count++;
}
void
wait() LOCKS_EXCLUDED(m_mutex)
2018-11-17 21:07:04 +00:00
{
Lock lock(&m_mutex);
m_mutex.Await(absl::Condition(this, &Semaphore::ready));
2018-11-17 21:07:04 +00:00
m_count--;
}
bool
waitFor(absl::Duration timeout) LOCKS_EXCLUDED(m_mutex)
2018-11-17 21:07:04 +00:00
{
Lock lock(&m_mutex);
2018-11-17 21:07:04 +00:00
if(!m_mutex.AwaitWithTimeout(absl::Condition(this, &Semaphore::ready),
timeout))
2018-11-17 21:07:04 +00:00
{
return false;
2018-11-17 21:07:04 +00:00
}
m_count--;
return true;
2018-11-17 21:07:04 +00:00
}
};
using Barrier = absl::Barrier;
2018-08-12 17:22:29 +00:00
} // namespace util
} // namespace llarp
2018-08-16 14:34:15 +00:00
#endif