66a92735cd485fa837a1ed1ef9322a250764e76a
[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::setStopFunc(std::function<void()> &&func)
45 {
46         std::lock_guard<std::mutex> l(this->m_flagMutex);
47         this->m_stopFunc = std::move(func);
48 }
49
50 void HandleExt::stop()
51 {
52         DEBUG("Stop & join worker...");
53
54         {
55                 std::lock_guard<std::mutex> l(this->m_flagMutex);
56                 this->m_stop = true;
57
58                 if (this->m_stopFunc != nullptr)
59                         this->m_stopFunc();
60         }
61
62         if (this->m_worker.joinable())
63                 this->m_worker.join();
64 }
65
66 bool HandleExt::isStopped() const
67 {
68         std::lock_guard<std::mutex> l(this->m_flagMutex);
69         return this->m_stop;
70 }
71
72 bool HandleExt::isRunning() const
73 {
74         std::lock_guard<std::mutex> l(this->m_flagMutex);
75         return this->m_isRunning;
76 }
77
78 void HandleExt::dispatchAsync(const std::shared_ptr<Task> &f)
79 {
80         std::lock_guard<std::mutex> l(this->m_flagMutex);
81
82         if (this->m_isRunning)
83                 ThrowExc(CSR_ERROR_BUSY, "Worker is already running. Async is busy!");
84
85         if (this->m_worker.joinable())
86                 this->m_worker.join();
87
88         this->m_isRunning = true;
89         this->m_stop = false;
90
91         this->m_worker = std::thread([this, f] {
92                 DEBUG("client async thread dispatched! tid: " << std::this_thread::get_id());
93
94                 {
95                         // Wait for client lib API func returned & mutex freed by scoped-lock dtor
96                         // This is for invoking registered callbacks follows returning API func
97                         std::lock_guard<std::mutex> _l(this->m_dispatchMutex);
98                 }
99                         (*f)();
100
101                 {
102                         std::lock_guard<std::mutex> _l(this->m_flagMutex);
103                         this->m_isRunning = false;
104                 }
105
106                 DEBUG("client async thread done! tid: " << std::this_thread::get_id());
107         });
108 }
109
110 void HandleExt::add(ResultPtr &&ptr)
111 {
112         std::lock_guard<std::mutex> l(this->m_resultsMutex);
113
114         this->m_results.emplace_back(std::move(ptr));
115 }
116
117 void HandleExt::add(ResultListPtr &&ptr)
118 {
119         std::lock_guard<std::mutex> l(this->m_resultsMutex);
120
121         this->m_resultLists.emplace_back(std::move(ptr));
122 }
123
124 } // namespace Client
125 } // namespace Csr