2 * Copyright (c) 2011 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 * @author Karol Majewski (k.majewski@samsung.com)
22 #ifndef WRTDEVICEAPIS_COMMONS_IEVENT_H_
23 #define WRTDEVICEAPIS_COMMONS_IEVENT_H_
26 #include <dpl/event/controller.h>
27 #include <dpl/mutex.h>
28 #include <dpl/shared_ptr.h>
29 #include <Commons/Exception.h>
30 #include <Commons/EventReceiver.h>
32 namespace WrtDeviceApis {
34 class IEventPrivateData
37 virtual ~IEventPrivateData()
41 class IEventController
43 DPL::SharedPtr<IEventPrivateData> m_privateData;
46 virtual void waitTillProcessed() = 0;
47 virtual void waitForAnswer() = 0;
48 virtual bool cancelRequest()
52 virtual bool changeCallToSynchronous() = 0;
53 virtual ~IEventController()
57 const DPL::SharedPtr<IEventPrivateData> &privateData)
59 m_privateData = privateData;
61 const DPL::SharedPtr<IEventPrivateData>& getPrivateData()
66 typedef DPL::SharedPtr<IEventController> IEventControllerPtr;
70 class IEvent : /*private DPL::WaitableEvent, */ public IEventController
73 friend class EventRequestReceiver<Super>;
74 friend class EventAnswerReceiver<Super>;
75 friend class SignalEventCall<Super>;
76 friend class EventReceiver<Super>;
80 HANDLING_NOT_SET = -1,
81 HANDLING_SYNCHRONOUS = 0,
82 HANDLING_ASYNCHRONOUS = 1,
83 HANDLING_SYNCHRONOUS_MANUAL_ANSWER = 2,
84 HANDLING_ASYNCHRONOUS_MANUAL_ANSWER = 3
91 STATE_REQUEST_RECEIVED,
93 STATE_ANSWER_RECEIVED,
95 STATE_CHANGED_TO_SYNCHRONOUS
102 m_state = STATE_ENDED;
103 m_exceptionCode = Commons::ExceptionCodes::EventCancelledException;
104 //if someone is waiting
105 signalSynchronousEventFlag();
109 DPL::Mutex m_stateMutex;
111 HandlingType m_handlingType;
112 EventAnswerReceiver< Super > *m_remoteController;
113 Commons::ExceptionCodes::Enumeration m_exceptionCode;
114 DPL::WaitableEvent *m_synchronousEventFlag;
115 DPL::WaitableEvent *m_finishedFlag;
116 DPL::WaitableEvent *m_cancelStatusFlag;
117 bool m_cancelSignalAhead;
119 bool m_cancelAllowed;
122 m_state(STATE_INITIAL),
123 m_handlingType(HANDLING_NOT_SET),
124 m_remoteController(NULL),
125 m_exceptionCode(Commons::ExceptionCodes::None),
126 m_synchronousEventFlag(NULL),
127 m_finishedFlag(NULL),
128 m_cancelStatusFlag(NULL),
129 m_cancelSignalAhead(false),
131 m_cancelAllowed(false)
134 virtual void waitForAnswer()
136 assert(HANDLING_SYNCHRONOUS == m_handlingType);
137 DPL::WaitForSingleHandle(m_synchronousEventFlag->GetHandle());
139 DPL::Mutex::ScopedLock lock(&m_stateMutex);
140 m_state = STATE_ENDED;
142 signalFinishedFlag();
143 LogDebug("deleting m_processEvent");
144 delete m_synchronousEventFlag;
145 m_synchronousEventFlag = NULL;
148 void signalFinishedFlag()
150 if (m_finishedFlag) {
151 m_finishedFlag->Signal();
155 DPL::WaitableEvent &getFinishedFlag()
157 if (!m_finishedFlag) {
158 m_finishedFlag = new DPL::WaitableEvent();
160 return *m_finishedFlag;
163 void signalCancelStatusFlag()
165 LogDebug("signaling cancel");
166 DPL::Mutex::ScopedLock lock(&m_stateMutex);
167 m_cancelSignalAhead = true;
168 if (m_cancelStatusFlag) {
169 m_cancelStatusFlag->Signal();
173 DPL::WaitableEvent &getCancelStatusFlag()
175 if (!m_cancelStatusFlag) {
176 m_cancelStatusFlag = new DPL::WaitableEvent();
178 return *m_cancelStatusFlag;
181 void signalSynchronousEventFlag()
183 if (m_synchronousEventFlag) {
184 m_synchronousEventFlag->Signal();
191 * Gets the answer receiver pointer.
193 EventAnswerReceiver< Super > * getAnswerReceiverRef() const
195 return m_remoteController;
200 delete m_cancelStatusFlag;
201 delete m_finishedFlag;
202 delete m_synchronousEventFlag;
205 virtual bool changeCallToSynchronous()
207 return setForSynchronousCall();
210 virtual void waitTillProcessed()
212 DPL::WaitForSingleHandle(getFinishedFlag().GetHandle());
213 delete m_finishedFlag;
214 m_finishedFlag = NULL;
217 virtual void clearOnCancel()
220 Commons::ExceptionCodes::Enumeration getExceptionCode() const
222 return m_exceptionCode;
224 void setExceptionCode(Commons::ExceptionCodes::Enumeration exceptionCode)
226 m_exceptionCode = exceptionCode;
229 short getHandlingType() const
231 return m_handlingType;
234 virtual bool setForSynchronousCall()
236 DPL::Mutex::ScopedLock lock(&m_stateMutex);
241 case STATE_ANSWER_SEND:
242 m_state = STATE_CHANGED_TO_SYNCHRONOUS;
244 case STATE_ANSWER_RECEIVED:
250 m_handlingType = HANDLING_SYNCHRONOUS;
254 virtual bool setForAsynchronousCall(
255 EventAnswerReceiver< Super > *remoteController)
257 DPL::Mutex::ScopedLock lock(&m_stateMutex);
262 case STATE_ANSWER_SEND:
263 case STATE_ANSWER_RECEIVED:
269 m_handlingType = HANDLING_ASYNCHRONOUS;
270 m_remoteController = remoteController;
275 * Normally, after invoking OnRequestReceived in RequestReceiver, the answer
276 * is being send automatically (after flow leaves OnRequestReceived).
277 * After calling this function, the answer is not being send automatically,
278 * you need to call ManualAnswer to send event back.
279 * It works both in asynchronous and synchronous handling type.
281 virtual bool switchToManualAnswer()
284 m_handlingType == HANDLING_ASYNCHRONOUS || m_handlingType ==
285 HANDLING_SYNCHRONOUS);
287 DPL::Mutex::ScopedLock lock(&m_stateMutex);
292 case STATE_ANSWER_SEND:
293 case STATE_ANSWER_RECEIVED:
300 switch (m_handlingType) {
301 case HANDLING_ASYNCHRONOUS:
302 m_handlingType = HANDLING_ASYNCHRONOUS_MANUAL_ANSWER;
304 case HANDLING_SYNCHRONOUS:
305 m_handlingType = HANDLING_SYNCHRONOUS_MANUAL_ANSWER;
313 bool checkCancelled()
315 //DPL::Mutex::ScopedLock lock(&m_stateMutex);
321 //DPL::Mutex::ScopedLock lock(&m_stateMutex);
323 Throw(Commons::EventCancelledException);
327 bool getCancelAllowed() const
329 return m_cancelAllowed;
332 void setCancelAllowed(bool cancelAllowed)
334 m_cancelAllowed = cancelAllowed;
339 LogDebug("trying to cancel");
340 assert(HANDLING_ASYNCHRONOUS == m_handlingType ||
341 HANDLING_ASYNCHRONOUS_MANUAL_ANSWER == m_handlingType);
342 bool signaled = false;
344 DPL::Mutex::ScopedLock lock(&m_stateMutex);
351 case STATE_ANSWER_SEND:
352 LogDebug("cancelling");
354 delete m_cancelStatusFlag;
355 m_cancelStatusFlag = NULL;
356 return m_cancelAllowed;
357 case STATE_ANSWER_RECEIVED:
363 LogDebug("cancelling");
365 signaled = m_cancelSignalAhead;
367 //create waitable handle
368 getCancelStatusFlag();
371 LogDebug("waiting for cancel flag");
373 DPL::WaitForSingleHandle(getCancelStatusFlag().GetHandle());
375 delete m_cancelStatusFlag;
376 m_cancelStatusFlag = NULL;
377 return m_cancelAllowed;
381 } // WrtDeviceApisCommon
383 #endif /* WRTDEVICEAPIS_COMMONS_IEVENT_H_ */