diff --git a/src/oatpp/core/async/Lock.cpp b/src/oatpp/core/async/Lock.cpp index 6ddedab1..415b9b2b 100644 --- a/src/oatpp/core/async/Lock.cpp +++ b/src/oatpp/core/async/Lock.cpp @@ -169,4 +169,30 @@ void LockGuard::unlock() { } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Misc + +CoroutineStarter synchronize(oatpp::async::Lock *lock, CoroutineStarter&& starter) { + + class Synchronized : public oatpp::async::Coroutine { + private: + oatpp::async::LockGuard m_lockGuard; + CoroutineStarter m_starter; + public: + + Synchronized(oatpp::async::Lock *lock, CoroutineStarter&& starter) + : m_lockGuard(lock) + , m_starter(std::forward(starter)) + {} + + Action act() override { + return m_lockGuard.lockAsync().next(std::move(m_starter)).next(finish()); + } + + }; + + return new Synchronized(lock, std::forward(starter)); + +} + }} diff --git a/src/oatpp/core/async/Lock.hpp b/src/oatpp/core/async/Lock.hpp index 5c27c490..3363c16d 100644 --- a/src/oatpp/core/async/Lock.hpp +++ b/src/oatpp/core/async/Lock.hpp @@ -140,42 +140,7 @@ public: }; -/** - * Convenience Synchronized coroutine template. It locks the lock and then starts the coroutine. - * It makes sure that coroutine is synchronized by the lock. - *

Usage:

- * `Synchronized(&lock, args...)` - *

Where:

- *
    - *
  • lock - &l:Lock; for synchronization.
  • - *
  • args - MyCoroutine constructor arguments.
  • - *
- * @tparam C - 'MyCoroutine' type. - */ -template -class Synchronized : public oatpp::async::Coroutine> { -private: - oatpp::async::LockGuard m_lockGuard; - CoroutineStarter m_starter; -public: - - /* - * Constructor template. - * @tparam ConstructorArgs - Coroutine constructor arguments types. - * @param lock - Synchronization &l:Lock;. - * @param args - Actual Coroutine constructor arguments. - */ - template - Synchronized(oatpp::async::Lock *lock, ConstructorArgs... args) - : m_lockGuard(lock) - , m_starter(C::start(args...)) - {} - - Action act() override { - return m_lockGuard.lockAsync().next(std::move(m_starter)).next(Synchronized::finish()); - } - -}; +CoroutineStarter synchronize(oatpp::async::Lock *lock, CoroutineStarter&& starter); }} diff --git a/test/oatpp/core/async/LockTest.cpp b/test/oatpp/core/async/LockTest.cpp index 8210c0b8..f7672fd7 100644 --- a/test/oatpp/core/async/LockTest.cpp +++ b/test/oatpp/core/async/LockTest.cpp @@ -82,14 +82,14 @@ public: }; -class TestCoroutine2 : public oatpp::async::Coroutine { +class NotSynchronizedCoroutine : public oatpp::async::Coroutine { private: char m_symbol; Buff *m_buff; v_int32 m_counter; public: - TestCoroutine2(char symbol, Buff *buff) + NotSynchronizedCoroutine(char symbol, Buff *buff) : m_symbol(symbol), m_buff(buff), m_counter(0) {} @@ -104,6 +104,25 @@ public: }; +class TestCoroutine2 : public oatpp::async::Coroutine { +private: + char m_symbol; + Buff *m_buff; + oatpp::async::Lock *m_lock; +public: + + TestCoroutine2(char symbol, Buff *buff, oatpp::async::Lock *lock) + : m_symbol(symbol) + , m_buff(buff) + , m_lock(lock) + {} + + Action act() override { + return oatpp::async::synchronize(m_lock, NotSynchronizedCoroutine::start(m_symbol, m_buff)).next(finish()); + } + +}; + void testMethod(char symbol, Buff *buff, oatpp::async::Lock *lock) { std::lock_guard lockGuard(*lock); @@ -159,7 +178,7 @@ void LockTest::onRun() { } for (v_int32 c = 128; c <= 200; c++) { - executor.execute>(&lock, (char)c, &buff); + executor.execute((char)c, &buff, &lock); } std::list threads;