kernel/eka/kernel/sutils.cpp
changeset 243 c7a0ce20c48c
parent 134 95847726fe57
child 254 1560c419b176
--- a/kernel/eka/kernel/sutils.cpp	Mon Jul 26 10:52:56 2010 +0100
+++ b/kernel/eka/kernel/sutils.cpp	Fri Aug 06 16:34:38 2010 +0100
@@ -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