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 {
35 class IEventPrivateData
38 virtual ~IEventPrivateData()
44 class IEventController
46 DPL::SharedPtr<IEventPrivateData> m_privateData;
48 virtual void waitTillProcessed() = 0;
49 virtual void waitForAnswer() = 0;
50 virtual bool cancelRequest()
54 virtual bool changeCallToSynchronous() = 0;
55 virtual ~IEventController()
60 const DPL::SharedPtr<IEventPrivateData> &privateData)
62 m_privateData = privateData;
64 const DPL::SharedPtr<IEventPrivateData>& getPrivateData()
69 typedef DPL::SharedPtr<IEventController> IEventControllerPtr;
74 class IEvent : /*private DPL::WaitableEvent, */ public IEventController
77 friend class EventRequestReceiver<Super>;
78 friend class EventAnswerReceiver<Super>;
79 friend class SignalEventCall<Super>;
80 friend class EventReceiver<Super>;
84 HANDLING_NOT_SET = -1,
85 HANDLING_SYNCHRONOUS = 0,
86 HANDLING_ASYNCHRONOUS = 1,
87 HANDLING_SYNCHRONOUS_MANUAL_ANSWER = 2,
88 HANDLING_ASYNCHRONOUS_MANUAL_ANSWER = 3
95 STATE_REQUEST_RECEIVED,
97 STATE_ANSWER_RECEIVED,
99 STATE_CHANGED_TO_SYNCHRONOUS
106 m_state = STATE_ENDED;
107 m_exceptionCode = Commons::ExceptionCodes::EventCancelledException;
108 //if someone is waiting
109 signalSynchronousEventFlag();
112 DPL::Mutex m_stateMutex;
114 HandlingType m_handlingType;
115 EventAnswerReceiver< Super > *m_remoteController;
116 Commons::ExceptionCodes::Enumeration m_exceptionCode;
117 DPL::WaitableEvent *m_synchronousEventFlag;
118 DPL::WaitableEvent *m_finishedFlag;
119 DPL::WaitableEvent *m_cancelStatusFlag;
121 bool m_cancelAllowed;
124 m_state(STATE_INITIAL),
125 m_handlingType(HANDLING_NOT_SET),
126 m_remoteController(NULL),
127 m_exceptionCode(Commons::ExceptionCodes::None),
128 m_synchronousEventFlag(NULL),
129 m_finishedFlag(NULL),
130 m_cancelStatusFlag(NULL),
132 m_cancelAllowed(false)
136 virtual void waitForAnswer()
138 assert(HANDLING_SYNCHRONOUS == m_handlingType);
139 DPL::WaitForSingleHandle(m_synchronousEventFlag->GetHandle());
141 DPL::Mutex::ScopedLock lock(&m_stateMutex);
142 m_state = STATE_ENDED;
144 signalFinishedFlag();
145 LogDebug("deleting m_processEvent");
146 delete m_synchronousEventFlag;
147 m_synchronousEventFlag = NULL;
150 void signalFinishedFlag()
152 if (m_finishedFlag) {
153 m_finishedFlag->Signal();
157 DPL::WaitableEvent &getFinishedFlag()
159 if (!m_finishedFlag) {
160 m_finishedFlag = new DPL::WaitableEvent();
162 return *m_finishedFlag;
165 void signalCancelStatusFlag()
167 LogDebug("signaling cancel");
168 getCancelStatusFlag().Signal();
171 DPL::WaitableEvent &getCancelStatusFlag()
173 if (!m_cancelStatusFlag) {
174 m_cancelStatusFlag = new DPL::WaitableEvent();
176 return *m_cancelStatusFlag;
179 void signalSynchronousEventFlag()
181 if (m_synchronousEventFlag) {
182 m_synchronousEventFlag->Signal();
189 * Gets the answer receiver pointer.
191 EventAnswerReceiver< Super > * getAnswerReceiverRef() const
193 return m_remoteController;
198 delete m_cancelStatusFlag;
199 delete m_finishedFlag;
200 delete m_synchronousEventFlag;
203 virtual bool changeCallToSynchronous()
205 return setForSynchronousCall();
208 virtual void waitTillProcessed()
210 DPL::WaitForSingleHandle(getFinishedFlag().GetHandle());
211 delete m_finishedFlag;
212 m_finishedFlag = NULL;
215 virtual void clearOnCancel()
219 Commons::ExceptionCodes::Enumeration getExceptionCode() const
221 return m_exceptionCode;
223 void setExceptionCode(Commons::ExceptionCodes::Enumeration exceptionCode)
225 m_exceptionCode = exceptionCode;
228 short getHandlingType() const
230 return m_handlingType;
233 virtual bool setForSynchronousCall()
235 DPL::Mutex::ScopedLock lock(&m_stateMutex);
240 case STATE_ANSWER_SEND:
241 m_state = STATE_CHANGED_TO_SYNCHRONOUS;
243 case STATE_ANSWER_RECEIVED:
249 m_handlingType = HANDLING_SYNCHRONOUS;
253 virtual bool setForAsynchronousCall(
254 EventAnswerReceiver< Super > *remoteController)
256 DPL::Mutex::ScopedLock lock(&m_stateMutex);
261 case STATE_ANSWER_SEND:
262 case STATE_ANSWER_RECEIVED:
268 m_handlingType = HANDLING_ASYNCHRONOUS;
269 m_remoteController = remoteController;
274 * Normally, after invoking OnRequestReceived in RequestReceiver, the answer is being send automatically (after flow leaves OnRequestReceived).
275 * After calling this function, the answer is not being send automatically, you need to call ManualAnswer to send event back.
276 * It works both in asynchronous and synchronous handling type.
278 virtual bool switchToManualAnswer()
281 m_handlingType == HANDLING_ASYNCHRONOUS || m_handlingType ==
282 HANDLING_SYNCHRONOUS);
284 DPL::Mutex::ScopedLock lock(&m_stateMutex);
289 case STATE_ANSWER_SEND:
290 case STATE_ANSWER_RECEIVED:
297 switch (m_handlingType) {
298 case HANDLING_ASYNCHRONOUS:
299 m_handlingType = HANDLING_ASYNCHRONOUS_MANUAL_ANSWER;
301 case HANDLING_SYNCHRONOUS:
302 m_handlingType = HANDLING_SYNCHRONOUS_MANUAL_ANSWER;
310 bool checkCancelled()
312 //DPL::Mutex::ScopedLock lock(&m_stateMutex);
318 //DPL::Mutex::ScopedLock lock(&m_stateMutex);
320 Throw(Commons::EventCancelledException);
324 bool getCancelAllowed() const
326 return m_cancelAllowed;
329 void setCancelAllowed(bool cancelAllowed)
331 m_cancelAllowed = cancelAllowed;
336 LogDebug("trying to cancel");
338 HANDLING_ASYNCHRONOUS == m_handlingType ||
339 HANDLING_ASYNCHRONOUS_MANUAL_ANSWER == m_handlingType);
341 DPL::Mutex::ScopedLock lock(&m_stateMutex);
348 case STATE_ANSWER_SEND:
349 LogDebug("cancelling");
351 delete m_cancelStatusFlag;
352 m_cancelStatusFlag = NULL;
353 return m_cancelAllowed;
354 case STATE_ANSWER_RECEIVED:
360 LogDebug("cancelling");
363 LogDebug("waiting for cancel flag");
364 DPL::WaitForSingleHandle(getCancelStatusFlag().GetHandle());
365 delete m_cancelStatusFlag;
366 m_cancelStatusFlag = NULL;
367 return m_cancelAllowed;
372 } // WrtDeviceApisCommon
374 #endif /* WRTDEVICEAPIS_COMMONS_IEVENT_H_ */