2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file popup_service_callbacks.cpp
18 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
20 * @brief Header of Security Caller class used by services socket callbacks
23 #ifndef SECURITY_CALLER_H__
24 #define SECURITY_CALLER_H__
26 #include <dpl/thread.h>
27 #include <dpl/assert.h>
28 #include <dpl/singleton.h>
30 #include <security_controller.h>
37 virtual void FinalizeSending() = 0;
38 virtual ~IEventHolder() {};
41 template<class EventType>
42 class EventHolderImpl : public IEventHolder
47 EventHolderImpl(const EventType& e) : event(e) {}
48 virtual void FinalizeSending()
50 LogDebug("sending real sync event");
51 CONTROLLER_POST_SYNC_EVENT(SecurityController, event);
56 * Because Security Controller is a DPL::Controler class, its events
57 * can be send only from a DPL managed thread. SecurityCallerTread class
58 * has been implemented as a workaround of that constraint.
59 * This class is a DPL managed thread that waits for requests
60 * from non DPL managed threads and when receives one it posts event
61 * to the Security Controler in charge of the calling thread.
65 class SecurityCallerThread : public DPL::Thread
68 pthread_mutex_t m_mutex2;
69 pthread_mutex_t m_mutex;
70 pthread_cond_t m_cond;
71 pthread_cond_t m_cond2;
74 IEventHolder* m_eventHolder;
75 pthread_mutex_t m_syncMutex;
78 SecurityCallerThread() :
80 m_mutex2(PTHREAD_MUTEX_INITIALIZER),
81 m_mutex(PTHREAD_MUTEX_INITIALIZER),
82 m_cond(PTHREAD_COND_INITIALIZER),
83 m_cond2(PTHREAD_COND_INITIALIZER),
87 m_syncMutex(PTHREAD_MUTEX_INITIALIZER)
89 LogDebug("constructor");
92 virtual ~SecurityCallerThread()
94 pthread_mutex_unlock(&m_syncMutex);
95 pthread_cond_destroy(&m_cond);
96 pthread_cond_destroy(&m_cond2);
97 pthread_mutex_destroy(&m_mutex2);
98 pthread_mutex_destroy(&m_mutex);
99 pthread_mutex_destroy(&m_syncMutex);
103 /* main routine of the SecurityCallerThread */
104 virtual int ThreadEntry()
106 LogDebug("SecurityCallerThread start");
107 pthread_mutex_lock(&m_mutex); // lock shared data
109 while (m_continue) // main loop
111 if (m_eventHolder) // if m_eventHolder is set, the request has been received
113 m_eventHolder->FinalizeSending(); // send actual event in charge of calling thread
114 delete m_eventHolder;
115 m_eventHolder = NULL;
116 LogDebug("setting finished state");
117 pthread_mutex_lock(&m_syncMutex); // lock m_finished
119 pthread_mutex_unlock(&m_syncMutex); // unlock m_finished
120 LogDebug("finished");
121 pthread_cond_signal(&m_cond2); // signal a calling thread that event has been posted.
123 LogDebug("waiting for event");
125 // unlock m_mutex, wait on m_cond until signal received, lock m_mutex
126 pthread_cond_wait(&m_cond, &m_mutex);
127 LogDebug("found an event");
130 pthread_mutex_unlock(&m_mutex);
138 LogDebug("Quit called");
139 pthread_mutex_lock(&m_mutex); // lock shared data
140 m_continue = false; // main loop condition set to false
141 pthread_mutex_unlock(&m_mutex); // unlock shard data
142 pthread_cond_signal(&m_cond);
145 template <class EventType>
146 void SendSyncEvent(const EventType& event)
148 // prevent SendSyncEvent being called by multiple threads at the same time.
149 pthread_mutex_lock(&m_mutex2);
150 LogDebug("sending sync event");
151 bool correct_thread = false;
153 LogDebug("Checking if this is unmanaged thread");
154 DPL::Thread::GetCurrentThread();
155 } Catch (DPL::Thread::Exception::UnmanagedThread) {
156 correct_thread = true;
158 Assert(correct_thread &&
159 "This method may not be called from DPL managed thread or main thread");
160 LogDebug("putting an event to be posted");
161 pthread_mutex_lock(&m_mutex); // lock shared data
162 Assert(m_eventHolder == NULL && "Whooops");
163 m_eventHolder = new EventHolderImpl<EventType>(event); // put an event to be posted
164 pthread_mutex_unlock(&m_mutex); // unlock shared data
165 LogDebug("Signal caller thread that new event has been created");
166 pthread_cond_signal(&m_cond); // signal SecurityCallerThread to wake up because new
167 // event is waiting to be posted
169 LogDebug("waiting untill send completes");
170 pthread_mutex_lock(&m_syncMutex); /* wait until send completes */
173 pthread_cond_wait(&m_cond2, &m_syncMutex); // wait until event is posted
177 pthread_mutex_unlock(&m_syncMutex);
178 pthread_mutex_unlock(&m_mutex2);
182 friend class DPL::Singleton<SecurityCallerThread>;
185 typedef DPL::Singleton<SecurityCallerThread> SecurityCallerSingleton;
189 #endif //SECURITY_CALLER_H__