Openssl: add thread support and fix initialization
[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 <crypto-init.h>
38
39 #include <cstdio>
40
41 #include <dpl/exception.h>
42
43 #include "generic-event.h"
44
45 namespace CKM {
46
47 class ServiceThread {
48 public:
49     typedef std::function<void(void)> EventDescription;
50     enum class State {
51         NoThread,
52         Work,
53     };
54
55     ServiceThread()
56       : m_state(State::NoThread)
57       , m_quit(false)
58     {}
59
60     void Create() {
61         assert(m_state == State::NoThread);
62         m_thread = std::thread(ThreadLoopStatic, this);
63         m_state = State::Work;
64     }
65
66     void Join() {
67         assert(m_state != State::NoThread);
68         {
69             std::lock_guard<std::mutex> lock(m_eventQueueMutex);
70             m_quit = true;
71             m_waitCondition.notify_one();
72         }
73         m_thread.join();
74         m_state = State::NoThread;
75     }
76
77     virtual ~ServiceThread()
78     {
79         assert((m_state == State::NoThread) && "Thread was not stopped before ServiceThread destruction!");
80     }
81
82 protected:
83     /*
84      * This function is always called from ThreadService::ThreadEvent where fun
85      * is created as a temporary object and therefore will not be copied.
86      */
87     void CreateEvent(std::function<void(void)> fun)
88     {
89         EventDescription description;
90         description = std::move(fun);
91         {
92             std::lock_guard<std::mutex> lock(m_eventQueueMutex);
93             m_eventQueue.push(description);
94         }
95         m_waitCondition.notify_one();
96     }
97
98     static void ThreadLoopStatic(ServiceThread *ptr) {
99         ptr->ThreadLoop();
100
101         // cleanup openssl in every thread
102         deinitOpenSslThread();
103     }
104
105     void ThreadLoop(){
106         for (;;) {
107             EventDescription description;
108             {
109                 std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
110                 if (m_quit)
111                     return;
112                 if (!m_eventQueue.empty()) {
113                     description = m_eventQueue.front();
114                     m_eventQueue.pop();
115                 } else {
116                     m_waitCondition.wait(ulock);
117                 }
118             }
119
120             if (description) {
121                 UNHANDLED_EXCEPTION_HANDLER_BEGIN
122                 {
123                     description();
124                 }
125                 UNHANDLED_EXCEPTION_HANDLER_END
126             }
127         }
128     }
129
130     std::thread m_thread;
131     std::mutex m_eventQueueMutex;
132     std::queue<EventDescription> m_eventQueue;
133     std::condition_variable m_waitCondition;
134
135     State m_state;
136     bool m_quit;
137 };
138
139 } // namespace CKM
140
141 #endif // _CENT_KEY_SERVICE_THREAD_