/usr/include/asio/detail/std_event.hpp is in libasio-dev 1:1.10.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | //
// detail/std_event.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_STD_EVENT_HPP
#define ASIO_DETAIL_STD_EVENT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)
#include <chrono>
#include <condition_variable>
#include "asio/detail/assert.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
class std_event
: private noncopyable
{
public:
// Constructor.
std_event()
: state_(0)
{
}
// Destructor.
~std_event()
{
}
// Signal the event. (Retained for backward compatibility.)
template <typename Lock>
void signal(Lock& lock)
{
this->signal_all(lock);
}
// Signal all waiters.
template <typename Lock>
void signal_all(Lock& lock)
{
ASIO_ASSERT(lock.locked());
(void)lock;
state_ |= 1;
cond_.notify_all();
}
// Unlock the mutex and signal one waiter.
template <typename Lock>
void unlock_and_signal_one(Lock& lock)
{
ASIO_ASSERT(lock.locked());
state_ |= 1;
bool have_waiters = (state_ > 1);
lock.unlock();
if (have_waiters)
cond_.notify_one();
}
// If there's a waiter, unlock the mutex and signal it.
template <typename Lock>
bool maybe_unlock_and_signal_one(Lock& lock)
{
ASIO_ASSERT(lock.locked());
state_ |= 1;
if (state_ > 1)
{
lock.unlock();
cond_.notify_one();
return true;
}
return false;
}
// Reset the event.
template <typename Lock>
void clear(Lock& lock)
{
ASIO_ASSERT(lock.locked());
(void)lock;
state_ &= ~std::size_t(1);
}
// Wait for the event to become signalled.
template <typename Lock>
void wait(Lock& lock)
{
ASIO_ASSERT(lock.locked());
unique_lock_adapter u_lock(lock);
while ((state_ & 1) == 0)
{
waiter w(state_);
cond_.wait(u_lock.unique_lock_);
}
}
// Timed wait for the event to become signalled.
template <typename Lock>
bool wait_for_usec(Lock& lock, long usec)
{
ASIO_ASSERT(lock.locked());
unique_lock_adapter u_lock(lock);
if ((state_ & 1) == 0)
{
waiter w(state_);
cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec));
}
return (state_ & 1) != 0;
}
private:
// Helper class to temporarily adapt a scoped_lock into a unique_lock so that
// it can be passed to std::condition_variable::wait().
struct unique_lock_adapter
{
template <typename Lock>
explicit unique_lock_adapter(Lock& lock)
: unique_lock_(lock.mutex().mutex_, std::adopt_lock)
{
}
~unique_lock_adapter()
{
unique_lock_.release();
}
std::unique_lock<std::mutex> unique_lock_;
};
// Helper to increment and decrement the state to track outstanding waiters.
class waiter
{
public:
explicit waiter(std::size_t& state)
: state_(state)
{
state_ += 2;
}
~waiter()
{
state_ -= 2;
}
private:
std::size_t& state_;
};
std::condition_variable cond_;
std::size_t state_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)
#endif // ASIO_DETAIL_STD_EVENT_HPP
|