Skip to content

Commit

Permalink
Merge pull request #89 from oatpp/beter_async_lock_api
Browse files Browse the repository at this point in the history
Beter async lock api
  • Loading branch information
lganzzzo committed Jun 22, 2019
2 parents 864a064 + e225432 commit 4ac6f25
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 37 deletions.
26 changes: 26 additions & 0 deletions src/oatpp/core/async/Lock.cpp
Expand Up @@ -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));

}

}}
39 changes: 5 additions & 34 deletions src/oatpp/core/async/Lock.hpp
Expand Up @@ -141,41 +141,12 @@ class LockGuard {
};

/**
* 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.
* Synchronize coroutine execution by lock.
* @param lock - &l:Lock; for synchronization.
* @param starter - Coroutine to execute in synchronized manner. &id:oatpp::async::CoroutineStarter;.
* @return - starter of synchronization coroutine (wrapper coroutine). &id:oatpp::async::CoroutineStarter;.
*/
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);

}}

Expand Down
25 changes: 22 additions & 3 deletions test/oatpp/core/async/LockTest.cpp
Expand Up @@ -82,14 +82,14 @@ class TestCoroutine : public oatpp::async::Coroutine<TestCoroutine> {

};

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)
{}

Expand All @@ -104,6 +104,25 @@ class TestCoroutine2 : public oatpp::async::Coroutine<TestCoroutine2> {

};

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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4ac6f25

Please sign in to comment.