Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ if(NOT CMAKE_CROSSCOMPILING AND BUILD_UNIT_TESTS)
tests/basics.test.cpp
tests/blocked_by.test.cpp
tests/cancel.test.cpp
tests/guards.test.cpp
tests/exclusive_access.test.cpp
tests/proxy.test.cpp
)

Expand Down
50 changes: 24 additions & 26 deletions modules/async_context.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -526,45 +526,47 @@ private:
sleep_duration m_pending_delay{ 0 };
};

export class context_token
export class exclusive_access
{
public:
constexpr context_token() = default;
constexpr context_token(context& p_capture) noexcept
: m_context_address(std::bit_cast<uptr>(&p_capture))
constexpr exclusive_access() = default;
constexpr exclusive_access(context& p_capture) noexcept
: m_context_address(&p_capture)
{
}
constexpr context_token& operator=(context& p_capture) noexcept

constexpr exclusive_access& operator=(context& p_capture) noexcept
{
m_context_address = std::bit_cast<uptr>(&p_capture);
m_context_address = &p_capture;
return *this;
}
constexpr context_token& operator=(nullptr_t) noexcept
constexpr exclusive_access& operator=(nullptr_t) noexcept
{
m_context_address = 0U;
m_context_address = nullptr;
return *this;
}

constexpr context_token(context_token const& p_capture) noexcept = default;
constexpr context_token& operator=(context_token const& p_capture) noexcept =
constexpr exclusive_access(exclusive_access const& p_capture) noexcept =
default;
constexpr context_token(context_token&& p_capture) noexcept = default;
constexpr context_token& operator=(context_token& p_capture) noexcept =
constexpr exclusive_access& operator=(
exclusive_access const& p_capture) noexcept = default;
constexpr exclusive_access(exclusive_access&& p_capture) noexcept = default;
constexpr exclusive_access& operator=(exclusive_access& p_capture) noexcept =
default;

constexpr bool operator==(context& p_context) noexcept
{
return m_context_address == std::bit_cast<uptr>(&p_context);
return m_context_address == &p_context;
}

[[nodiscard]] constexpr bool in_use() const noexcept
{
return m_context_address != 0U;
return m_context_address != nullptr;
}

[[nodiscard]] auto address() const noexcept
{
return m_context_address != 0U;
return m_context_address != nullptr;
}

[[nodiscard]] constexpr operator bool() const noexcept
Expand All @@ -576,31 +578,27 @@ public:
// unblocks and clear itself.
constexpr void lease(context& p_capture) noexcept
{
m_context_address = std::bit_cast<uptr>(&p_capture);
m_context_address = &p_capture;
}

constexpr std::suspend_always set_as_block_by_sync(context& p_capture)
{
if (in_use()) {
auto* address = std::bit_cast<void*>(m_context_address);
auto* inner_context = static_cast<context*>(address);
p_capture.block_by_sync(inner_context);
p_capture.block_by_sync(m_context_address);
}
return {};
}

constexpr void unblock_and_clear() noexcept
{
if (in_use()) {
auto* address = std::bit_cast<void*>(m_context_address);
auto* inner_context = static_cast<context*>(address);
inner_context->unblock();
m_context_address = 0U;
m_context_address->unblock();
m_context_address = nullptr;
}
}

private:
uptr m_context_address = 0U;
context* m_context_address = nullptr;
};

export struct io
Expand All @@ -614,11 +612,11 @@ export struct io

export struct sync
{
sync(context_token p_context)
sync(exclusive_access p_context)
: m_context(p_context)
{
}
context_token m_context;
exclusive_access m_context;
};

// =============================================================================
Expand Down
2 changes: 1 addition & 1 deletion tests/guards.test.cpp → tests/exclusive_access.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ boost::ut::suite<"guards_tests"> guards_tests = []() {
test_context ctx1;
test_context ctx2;

async::context_token io_in_use;
async::exclusive_access io_in_use;

auto single_resource =
[&](async::context& p_context) -> async::future<void> {
Expand Down