diff options
author | elfmz <fenix1905@tut.by> | 2022-02-15 22:15:50 +0300 |
---|---|---|
committer | elfmz <fenix1905@tut.by> | 2022-02-15 22:15:50 +0300 |
commit | a7b531abe9b481704d054d82185627289df57ff1 (patch) | |
tree | 462335b9e3da004c4f8954d37b98b2b5309ec60b /far2l/src/base | |
parent | 9dfd5a6784a13b356dc6f147d9ba6e09e0b384b7 (diff) |
continue Message() refactor..
Diffstat (limited to 'far2l/src/base')
-rw-r--r-- | far2l/src/base/InterThreadCall.cpp | 42 | ||||
-rw-r--r-- | far2l/src/base/InterThreadCall.hpp | 57 |
2 files changed, 64 insertions, 35 deletions
diff --git a/far2l/src/base/InterThreadCall.cpp b/far2l/src/base/InterThreadCall.cpp index e29962a4..54d0b1f4 100644 --- a/far2l/src/base/InterThreadCall.cpp +++ b/far2l/src/base/InterThreadCall.cpp @@ -51,6 +51,29 @@ void OverrideInterThreadID(unsigned int tid) g_thread_id = tid; } +void InterThreadSyncCallDelegate::Finalize(bool discarded) +{ + std::lock_guard<std::mutex> lock(_mtx); + _discarded = discarded; + _done = true; + _cond.notify_all(); +} + +bool InterThreadSyncCallDelegate::Do() +{ + _done = _discarded = false; + + if (UNLIKELY(!EnqueueInterThreadCallDelegate(this))) + return false; + + std::unique_lock<std::mutex> lock(_mtx); + while (!_done) { + _cond.wait(lock); + } + + return !_discarded; +} + InterThreadCallsDispatcherThread::InterThreadCallsDispatcherThread() { const DWORD self_tid = GetInterThreadID(); @@ -68,7 +91,11 @@ InterThreadCallsDispatcherThread::~InterThreadCallsDispatcherThread() interlocked_delegates.swap(s_interlocked_delegates); } for (const auto &d : interlocked_delegates) { - d->Process(true); + try { + d->Finalize(true); + } catch (std::exception &e) { + fprintf(stderr, "%s - Finalize: %s\n", __FUNCTION__, e.what()); + } } } @@ -92,7 +119,18 @@ int DispatchInterThreadCalls() interlocked_delegates.swap(s_interlocked_delegates); } for (const auto &d : interlocked_delegates) { - d->Process(false); + bool failed = false; + try { + d->Process(); + } catch (std::exception &e) { + fprintf(stderr, "%s - Process: %s\n", __FUNCTION__, e.what()); + failed = true; + } + try { + d->Finalize(failed); + } catch (std::exception &e) { + fprintf(stderr, "%s - Finalize: %s\n", __FUNCTION__, e.what()); + } } dispatched_count+= (int)interlocked_delegates.size(); } diff --git a/far2l/src/base/InterThreadCall.hpp b/far2l/src/base/InterThreadCall.hpp index e5ea25be..ab450718 100644 --- a/far2l/src/base/InterThreadCall.hpp +++ b/far2l/src/base/InterThreadCall.hpp @@ -7,7 +7,8 @@ struct IInterThreadCallDelegate { virtual ~IInterThreadCallDelegate() {} - virtual void Process(bool stopping) = 0; + virtual void Process() = 0; + virtual void Finalize(bool discarded) = 0; }; // similar to Windows GetCurrentThreadId() but with ability to be overriden @@ -28,46 +29,34 @@ int DispatchInterThreadCalls(); bool EnqueueInterThreadCallDelegate(IInterThreadCallDelegate *d); -template <class RV, class FN> - class InterThreadCallDelegate : protected IInterThreadCallDelegate +class InterThreadSyncCallDelegate : public IInterThreadCallDelegate { +protected: std::mutex _mtx; std::condition_variable _cond; bool _done, _discarded; + +public: + virtual void Finalize(bool discarded); + bool Do(); +}; + +template <class RV, class FN> + class InterThreadSyncCallDelegateImpl : public InterThreadSyncCallDelegate +{ FN _fn; RV _rv; protected: - virtual void Process(bool stopping) + virtual void Process() { - if (LIKELY(!stopping)) - _rv = _fn(); - - std::lock_guard<std::mutex> lock(_mtx); - _discarded = stopping; - _done = true; - _cond.notify_all(); + _rv = _fn(); } public: - inline InterThreadCallDelegate(FN fn):_fn(fn) { } + inline InterThreadSyncCallDelegateImpl(const FN &fn) : _fn(fn) { } - bool Do() - { - _done = _discarded = false; - - if (UNLIKELY(!EnqueueInterThreadCallDelegate(this))) - return false; - - std::unique_lock<std::mutex> lock(_mtx); - while (!_done) { - _cond.wait(lock); - } - - return !_discarded; - } - - inline RV Result() const + inline const RV &Result() const { return _rv; } @@ -79,16 +68,18 @@ template <class FN> FN _fn; protected: - virtual void Process(bool stopping) + virtual void Process() { - if (LIKELY(!stopping)) - _fn(); + _fn(); + } + virtual void Finalize(bool discarded) + { delete this; } public: - inline InterThreadAsyncCallDelegate(FN fn):_fn(fn) { } + inline InterThreadAsyncCallDelegate(const FN &fn) : _fn(fn) { } bool Enqueue() { @@ -111,7 +102,7 @@ template <class RV, RV FAIL_RV = (RV)0, class FN> return fn(); } - InterThreadCallDelegate<RV, FN> c(fn); + InterThreadSyncCallDelegateImpl<RV, FN> c(fn); if (LIKELY(c.Do())) { return c.Result(); } |