aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/event.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/event.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/event.cpp')
-rw-r--r--util/system/event.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/util/system/event.cpp b/util/system/event.cpp
new file mode 100644
index 0000000000..79b3cdb291
--- /dev/null
+++ b/util/system/event.cpp
@@ -0,0 +1,137 @@
+#include "datetime.h"
+#include "defaults.h"
+
+#include <cstdio>
+
+#include "atomic.h"
+#include "event.h"
+#include "mutex.h"
+#include "condvar.h"
+
+#ifdef _win_
+ #include "winint.h"
+#endif
+
+class TSystemEvent::TEvImpl: public TAtomicRefCount<TSystemEvent::TEvImpl> {
+public:
+#ifdef _win_
+ inline TEvImpl(ResetMode rmode) {
+ cond = CreateEvent(nullptr, rmode == rManual ? true : false, false, nullptr);
+ }
+
+ inline ~TEvImpl() {
+ CloseHandle(cond);
+ }
+
+ inline void Reset() noexcept {
+ ResetEvent(cond);
+ }
+
+ inline void Signal() noexcept {
+ SetEvent(cond);
+ }
+
+ inline bool WaitD(TInstant deadLine) noexcept {
+ if (deadLine == TInstant::Max()) {
+ return WaitForSingleObject(cond, INFINITE) == WAIT_OBJECT_0;
+ }
+
+ const TInstant now = Now();
+
+ if (now < deadLine) {
+ //TODO
+ return WaitForSingleObject(cond, (deadLine - now).MilliSeconds()) == WAIT_OBJECT_0;
+ }
+
+ return (WaitForSingleObject(cond, 0) == WAIT_OBJECT_0);
+ }
+#else
+ inline TEvImpl(ResetMode rmode)
+ : Manual(rmode == rManual ? true : false)
+ {
+ }
+
+ inline void Signal() noexcept {
+ if (Manual && AtomicGet(Signaled)) {
+ return; // shortcut
+ }
+
+ with_lock (Mutex) {
+ AtomicSet(Signaled, 1);
+ }
+
+ if (Manual) {
+ Cond.BroadCast();
+ } else {
+ Cond.Signal();
+ }
+ }
+
+ inline void Reset() noexcept {
+ AtomicSet(Signaled, 0);
+ }
+
+ inline bool WaitD(TInstant deadLine) noexcept {
+ if (Manual && AtomicGet(Signaled)) {
+ return true; // shortcut
+ }
+
+ bool resSignaled = true;
+
+ with_lock (Mutex) {
+ while (!AtomicGet(Signaled)) {
+ if (!Cond.WaitD(Mutex, deadLine)) {
+ resSignaled = AtomicGet(Signaled); // timed out, but Signaled could have been set
+
+ break;
+ }
+ }
+
+ if (!Manual) {
+ AtomicSet(Signaled, 0);
+ }
+ }
+
+ return resSignaled;
+ }
+#endif
+
+private:
+#ifdef _win_
+ HANDLE cond;
+#else
+ TCondVar Cond;
+ TMutex Mutex;
+ TAtomic Signaled = 0;
+ bool Manual;
+#endif
+};
+
+TSystemEvent::TSystemEvent(ResetMode rmode)
+ : EvImpl_(new TEvImpl(rmode))
+{
+}
+
+TSystemEvent::TSystemEvent(const TSystemEvent& other) noexcept
+ : EvImpl_(other.EvImpl_)
+{
+}
+
+TSystemEvent& TSystemEvent::operator=(const TSystemEvent& other) noexcept {
+ EvImpl_ = other.EvImpl_;
+ return *this;
+}
+
+TSystemEvent::~TSystemEvent() = default;
+
+void TSystemEvent::Reset() noexcept {
+ EvImpl_->Reset();
+}
+
+void TSystemEvent::Signal() noexcept {
+ EvImpl_->Signal();
+}
+
+bool TSystemEvent::WaitD(TInstant deadLine) noexcept {
+ return EvImpl_->WaitD(deadLine);
+}