kernel/eka/kernel/sutils.cpp
changeset 247 d8d70de2bd36
parent 152 657f875b013e
child 254 1560c419b176
--- a/kernel/eka/kernel/sutils.cpp	Tue Jul 06 15:50:07 2010 +0300
+++ b/kernel/eka/kernel/sutils.cpp	Wed Aug 18 11:08:29 2010 +0300
@@ -3548,10 +3548,19 @@
 
 void TClientRequest::EndComplete(DThread* aThread)
 	{
+	// NB: if the callback is successfully queued, the target thread may run and
+	// process it before we get back from the call to QueueUserModeCallback().
+	// In that case, 'iStatus' will be changed; and in general it is not safe to
+	// look at any element of 'this' once the callback is queued, as it may change
+	// asynchronously.  Therefore, we must cache the value of 'iStatus' beforehand
+	// and later use this saved copy to decide whether to signal the target thread.
+	T_UintPtr status = iStatus;
 	TInt r = NKern::QueueUserModeCallback(&aThread->iNThread, this);
+
 	if (r == KErrNone)
 		{
-		if (iStatus != (KClientRequestNullStatus | KClientRequestFlagInUse))
+		__NK_ASSERT_DEBUG(status & KClientRequestFlagInUse);
+		if ((status & ~KClientRequestFlagInUse) != KClientRequestNullStatus)
 			NKern::ThreadRequestSignal(&aThread->iNThread);
 		}
 	else