Cancel signal fix
authorLukasz Marek <l.marek@samsung.com>
Mon, 29 Apr 2013 16:27:27 +0000 (18:27 +0200)
committerGerrit Code Review <gerrit2@kim11>
Tue, 30 Apr 2013 12:34:24 +0000 (21:34 +0900)
[Issue#]   N/A
[Bug]      Widget can hang when event cancelled.
[Cause]    WaitableHandle can be signalled before it is explicity created.
[Solution] Add a flag to mark signalling.

Change-Id: I67d71a771250967d5f105bdcf7eb40d3ec2bef5c

src/Commons/IEvent.h

index 7764fde..207f5bb 100644 (file)
@@ -114,6 +114,7 @@ class IEvent : /*private DPL::WaitableEvent, */ public IEventController
     DPL::WaitableEvent *m_synchronousEventFlag;
     DPL::WaitableEvent *m_finishedFlag;
     DPL::WaitableEvent *m_cancelStatusFlag;
+    bool m_cancelSignalAhead;
     bool m_cancelled;
     bool m_cancelAllowed;
 
@@ -125,6 +126,7 @@ class IEvent : /*private DPL::WaitableEvent, */ public IEventController
         m_synchronousEventFlag(NULL),
         m_finishedFlag(NULL),
         m_cancelStatusFlag(NULL),
+        m_cancelSignalAhead(false),
         m_cancelled(false),
         m_cancelAllowed(false)
     {}
@@ -161,6 +163,8 @@ class IEvent : /*private DPL::WaitableEvent, */ public IEventController
     void signalCancelStatusFlag()
     {
         LogDebug("signaling cancel");
+        DPL::Mutex::ScopedLock lock(&m_stateMutex);
+        m_cancelSignalAhead = true;
         if (m_cancelStatusFlag) {
             m_cancelStatusFlag->Signal();
         }
@@ -333,9 +337,9 @@ class IEvent : /*private DPL::WaitableEvent, */ public IEventController
     bool cancelRequest()
     {
         LogDebug("trying to cancel");
-        assert(
-            HANDLING_ASYNCHRONOUS == m_handlingType ||
-            HANDLING_ASYNCHRONOUS_MANUAL_ANSWER == m_handlingType);
+        assert(HANDLING_ASYNCHRONOUS == m_handlingType ||
+               HANDLING_ASYNCHRONOUS_MANUAL_ANSWER == m_handlingType);
+        bool signaled = false;
         {
             DPL::Mutex::ScopedLock lock(&m_stateMutex);
             if (m_cancelled) {
@@ -358,12 +362,16 @@ class IEvent : /*private DPL::WaitableEvent, */ public IEventController
             }
             LogDebug("cancelling");
             m_cancelled = true;
+            signaled = m_cancelSignalAhead;
+            if (!signaled) {
+                //create waitable handle
+                getCancelStatusFlag();
+            }
         }
         LogDebug("waiting for cancel flag");
-
-#if 0   // temporary fix for ApplicationLaunchAppControl eventhandling
-        DPL::WaitForSingleHandle(getCancelStatusFlag().GetHandle());
-#endif
+        if (!signaled) {
+            DPL::WaitForSingleHandle(getCancelStatusFlag().GetHandle());
+        }
         delete m_cancelStatusFlag;
         m_cancelStatusFlag = NULL;
         return m_cancelAllowed;