diff --git a/include/ircd/ctx/ctx.h b/include/ircd/ctx/ctx.h index cabfc68f8..cd33f778e 100644 --- a/include/ircd/ctx/ctx.h +++ b/include/ircd/ctx/ctx.h @@ -83,7 +83,6 @@ namespace ircd::ctx #include "upgrade_lock.h" #include "unlock_guard.h" #include "condition_variable.h" -#include "peek.h" #include "view.h" #include "shared_state.h" #include "promise.h" diff --git a/include/ircd/ctx/peek.h b/include/ircd/ctx/peek.h deleted file mode 100644 index 1cdc6df26..000000000 --- a/include/ircd/ctx/peek.h +++ /dev/null @@ -1,150 +0,0 @@ -// Matrix Construct -// -// Copyright (C) Matrix Construct Developers, Authors & Contributors -// Copyright (C) 2016-2018 Jason Volk -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice is present in all copies. The -// full license for this software is available in the LICENSE file. - -#pragma once -#define HAVE_IRCD_CTX_PEEK_H - -namespace ircd::ctx -{ - template class peek; -} - -/// Device for a context to share data on its stack with others while yielding -/// -/// The peek yields a context while other contexts examine the object pointed -/// to in the peek. This allows a producing context to construct something -/// on its stack and then wait for the consuming contexts to do something with -/// that data before the producer resumes and potentially destroys the data. -/// This creates a very simple and lightweight single-producer/multi-consumer -/// queue mechanism using only context switching. -/// -/// Consumers get one chance to safely peek the data when a call to wait() -/// returns. Once the consumer context yields again for any reason the data is -/// potentially invalid. The data can only be peeked once by the consumer -/// because the second call to wait() will yield until the next data is -/// made available by the producer, not the same data. -/// -/// Producers will share an object during the call to notify(). Once the call -/// to notify() returns all consumers have peeked the data and the producer is -/// free to destroy it. -/// -template -class ircd::ctx::peek -{ - T *t {nullptr}; - dock a, b; - - bool ready() const; - - public: - size_t waiting() const; - - // Consumer interface; - template T &wait_until(time_point&&); - template T &wait_for(const duration &); - T &wait(); - - // Producer interface; - void notify(T &); - - peek() = default; - ~peek() noexcept; -}; - -template -ircd::ctx::peek::~peek() -noexcept -{ - assert(!waiting()); -} - -template -void -ircd::ctx::peek::notify(T &t) -{ - const unwind afterward{[this] - { - assert(a.empty()); - this->t = nullptr; - if(!b.empty()) - { - b.notify_all(); - yield(); - } - }}; - - assert(b.empty()); - this->t = &t; - a.notify_all(); - yield(); -} - -template -T & -ircd::ctx::peek::wait() -{ - b.wait([this] - { - return !ready(); - }); - - a.wait([this] - { - return ready(); - }); - - assert(t != nullptr); - return *t; -} - -template -template -T & -ircd::ctx::peek::wait_for(const duration &dur) -{ - return wait_until(now() + dur); -} - -template -template -T & -ircd::ctx::peek::wait_until(time_point&& tp) -{ - if(!b.wait_until(tp, [this] - { - return !ready(); - })) - throw timeout(); - - if(!a.wait_until(tp, [this] - { - return ready(); - })) - throw timeout(); - - assert(t != nullptr); - return *t; -} - -template -size_t -ircd::ctx::peek::waiting() -const -{ - return a.size() + b.size(); -} - -template -bool -ircd::ctx::peek::ready() -const -{ - return t != nullptr; -}