2b0609bddb249cbf9cc98bed1512ed4cc649151d
[platform/core/security/key-manager.git] / src / manager / main / service-thread.h
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bumjin Im <bj.im@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18 /*
19  * @file        service-thread.h
20  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
21  * @author      Zofia Abramowska (z.abramowska@samsung.com)
22  * @version     1.0
23  * @brief       Implementation of threads.
24  */
25
26 #ifndef _CENT_KEY_SERVICE_THREAD_
27 #define _CENT_KEY_SERVICE_THREAD_
28
29 #include <cassert>
30 #include <queue>
31 #include <mutex>
32 #include <thread>
33 #include <memory>
34 #include <functional>
35 #include <condition_variable>
36
37 #include <cstdio>
38
39 #include <dpl/exception.h>
40
41 #include "generic-event.h"
42
43 namespace CKM {
44
45 class ServiceThread {
46 public:
47     typedef std::function<void(void)> EventDescription;
48     enum class State {
49         NoThread,
50         Work,
51     };
52
53     ServiceThread()
54       : m_state(State::NoThread)
55       , m_quit(false)
56     {}
57
58     void Create() {
59         assert(m_state == State::NoThread);
60         m_thread = std::thread(ThreadLoopStatic, this);
61         m_state = State::Work;
62     }
63
64     void Join() {
65         assert(m_state != State::NoThread);
66         {
67             std::lock_guard<std::mutex> lock(m_eventQueueMutex);
68             m_quit = true;
69             m_waitCondition.notify_one();
70         }
71         m_thread.join();
72         m_state = State::NoThread;
73     }
74
75     virtual ~ServiceThread()
76     {
77         assert((m_state == State::NoThread) && "Thread was not stopped before ServiceThread destruction!");
78     }
79
80 protected:
81     /*
82      * This function is always called from ThreadService::ThreadEvent where fun
83      * is created as a temporary object and therefore will not be copied.
84      */
85     void CreateEvent(std::function<void(void)> fun)
86     {
87         EventDescription description;
88         description = std::move(fun);
89         {
90             std::lock_guard<std::mutex> lock(m_eventQueueMutex);
91             m_eventQueue.push(description);
92         }
93         m_waitCondition.notify_one();
94     }
95
96     static void ThreadLoopStatic(ServiceThread *ptr) {
97         ptr->ThreadLoop();
98     }
99
100     void ThreadLoop(){
101         for (;;) {
102             EventDescription description;
103             {
104                 std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
105                 if (m_quit)
106                     return;
107                 if (!m_eventQueue.empty()) {
108                     description = m_eventQueue.front();
109                     m_eventQueue.pop();
110                 } else {
111                     m_waitCondition.wait(ulock);
112                 }
113             }
114
115             if (description) {
116                 UNHANDLED_EXCEPTION_HANDLER_BEGIN
117                 {
118                     description();
119                 }
120                 UNHANDLED_EXCEPTION_HANDLER_END
121             }
122         }
123     }
124
125     std::thread m_thread;
126     std::mutex m_eventQueueMutex;
127     std::queue<EventDescription> m_eventQueue;
128     std::condition_variable m_waitCondition;
129
130     State m_state;
131     bool m_quit;
132 };
133
134 } // namespace CKM
135
136 #endif // _CENT_KEY_SERVICE_THREAD_