Wait to start async client subthread until api returned
[platform/upstream/csr-framework.git] / src / framework / client / handle-ext.cpp
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file        handle-ext.cpp
18  * @author      Kyungwook Tak (k.tak@samsung.com)
19  * @version     1.0
20  * @brief       handle with async request extension
21  */
22 #include "client/handle-ext.h"
23
24 #include <utility>
25
26 #include "common/audit/logger.h"
27 #include "common/exception.h"
28
29 namespace Csr {
30 namespace Client {
31
32 HandleExt::HandleExt(SockId id, ContextShPtr &&context) :
33         Handle(id, std::move(context)), m_stop(false), m_isRunning(false)
34 {
35 }
36
37 HandleExt::~HandleExt()
38 {
39         DEBUG("Destroying extended handle... join worker...");
40         if (this->m_worker.joinable())
41                 this->m_worker.join();
42 }
43
44 void HandleExt::stop()
45 {
46         DEBUG("Stop & join worker...");
47
48         {
49                 std::lock_guard<std::mutex> l(this->m_flagMutex);
50                 this->m_stop = true;
51         }
52
53         if (this->m_worker.joinable())
54                 this->m_worker.join();
55 }
56
57 bool HandleExt::isStopped() const
58 {
59         std::lock_guard<std::mutex> l(this->m_flagMutex);
60         return this->m_stop;
61 }
62
63 bool HandleExt::isRunning() const
64 {
65         std::lock_guard<std::mutex> l(this->m_flagMutex);
66         return this->m_isRunning;
67 }
68
69 void HandleExt::dispatchAsync(const std::shared_ptr<Task> &f)
70 {
71         std::lock_guard<std::mutex> l(this->m_flagMutex);
72
73         if (this->m_isRunning)
74                 ThrowExc(CSR_ERROR_BUSY, "Worker is already running. Async is busy!");
75
76         if (this->m_worker.joinable())
77                 this->m_worker.join();
78
79         this->m_isRunning = true;
80         this->m_stop = false;
81
82         this->m_worker = std::thread([this, f] {
83                 DEBUG("client async thread dispatched! tid: " << std::this_thread::get_id());
84
85                 {
86                         // Wait for client lib API func returned & mutex freed by scoped-lock dtor
87                         // This is for invoking registered callbacks follows returning API func
88                         std::lock_guard<std::mutex> _l(this->m_dispatchMutex);
89                 }
90                         (*f)();
91
92                 {
93                         std::lock_guard<std::mutex> _l(this->m_flagMutex);
94                         this->m_isRunning = false;
95                 }
96
97                 DEBUG("client async thread done! tid: " << std::this_thread::get_id());
98         });
99 }
100
101 void HandleExt::add(ResultPtr &&ptr)
102 {
103         std::lock_guard<std::mutex> l(this->m_resultsMutex);
104
105         this->m_results.emplace_back(std::move(ptr));
106 }
107
108 void HandleExt::add(ResultListPtr &&ptr)
109 {
110         std::lock_guard<std::mutex> l(this->m_resultsMutex);
111
112         this->m_resultLists.emplace_back(std::move(ptr));
113 }
114
115 } // namespace Client
116 } // namespace Csr