afa3fe6a6900be7c9884828261280cc013501999
[WebKit-https.git] / Source / bmalloc / bmalloc / AsyncTask.cpp
1 #include "AsyncTask.h"
2 #include "NoInline.h"
3
4 namespace bmalloc {
5
6 template<typename Function>
7 NO_INLINE void AsyncTask<Function>::runSlowCase()
8 {
9     State oldState = m_state.exchange(Signaled);
10     if (oldState == Signaled || oldState == Running)
11         return;
12
13     if (oldState == Sleeping) {
14         m_condition.notify_one();
15         return;
16     }
17
18     ASSERT(oldState == Exited);
19     pthread_create(&m_thread, nullptr, &pthreadEntryPoint, this);
20     pthread_detach(m_thread);
21 }
22
23 template<typename Function>
24 void* AsyncTask<Function>::pthreadEntryPoint(void* asyncTask)
25 {
26     static_cast<AsyncTask*>(asyncTask)->entryPoint();
27     return nullptr;
28 }
29
30 template<typename Function>
31 void AsyncTask<Function>::entryPoint()
32 {
33     State expectedState;
34     while (1) {
35         expectedState = Signaled;
36         if (m_state.compare_exchange_weak(expectedState, Running)) {
37             m_function();
38             continue;
39         }
40
41         expectedState = Running;
42         if (m_state.compare_exchange_weak(expectedState, Sleeping)) {
43             std::mutex dummy; // No need for a real mutex because there's only one waiting thread.
44             std::unique_lock<std::mutex> lock(dummy);
45             m_condition.wait_for(lock, std::chrono::milliseconds(2), [=]() { return this->m_state != Sleeping; });
46             continue;
47         }
48
49         expectedState = Sleeping;
50         if (m_state.compare_exchange_weak(expectedState, Exited))
51             break;
52     }
53 }
54
55 } // namespace bmalloc