better oatpp::async::synchronize API

This commit is contained in:
lganzzzo 2019-06-23 00:14:32 +03:00
parent 4f705c18ed
commit 474a6ca9ef
3 changed files with 49 additions and 39 deletions

View File

@ -169,4 +169,30 @@ void LockGuard::unlock() {
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Misc
CoroutineStarter synchronize(oatpp::async::Lock *lock, CoroutineStarter&& starter) {
class Synchronized : public oatpp::async::Coroutine<Synchronized> {
private:
oatpp::async::LockGuard m_lockGuard;
CoroutineStarter m_starter;
public:
Synchronized(oatpp::async::Lock *lock, CoroutineStarter&& starter)
: m_lockGuard(lock)
, m_starter(std::forward<CoroutineStarter>(starter))
{}
Action act() override {
return m_lockGuard.lockAsync().next(std::move(m_starter)).next(finish());
}
};
return new Synchronized(lock, std::forward<CoroutineStarter>(starter));
}
}}

View File

@ -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.
* <p><b>Usage:</b></p>
* `Synchronized<MyCoroutine>(&lock, args...)`
* <p><b>Where:</b></p>
* <ul>
* <li>lock - &l:Lock; for synchronization.</li>
* <li>args - MyCoroutine constructor arguments.</li>
* </ul>
* @tparam C - 'MyCoroutine' type.
*/
template<class C>
class Synchronized : public oatpp::async::Coroutine<Synchronized<C>> {
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<typename ...ConstructorArgs>
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);
}}

View File

@ -82,14 +82,14 @@ public:
};
class TestCoroutine2 : public oatpp::async::Coroutine<TestCoroutine2> {
class NotSynchronizedCoroutine : public oatpp::async::Coroutine<NotSynchronizedCoroutine> {
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<TestCoroutine2> {
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<oatpp::async::Lock> lockGuard(*lock);
@ -159,7 +178,7 @@ void LockTest::onRun() {
}
for (v_int32 c = 128; c <= 200; c++) {
executor.execute<oatpp::async::Synchronized<TestCoroutine2>>(&lock, (char)c, &buff);
executor.execute<TestCoroutine2>((char)c, &buff, &lock);
}
std::list<std::thread> threads;