kernel/eka/kernel/arm/cipc.cia
changeset 102 ef2a444a7410
parent 0 a41df078684a
child 109 b3a1d9898418
--- a/kernel/eka/kernel/arm/cipc.cia	Fri Apr 16 16:24:37 2010 +0300
+++ b/kernel/eka/kernel/arm/cipc.cia	Mon May 03 13:47:38 2010 +0300
@@ -57,7 +57,7 @@
 
 __NAKED__ void ExecHandler::MessageComplete(RMessageK* /*aMsg*/, TInt /*aReason*/)
 	{
-	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));		// get iFunction, as per preprocessor
+	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// get iFunction, as per preprocessor
 
 	// Subroutine MessageComplete
 	// Complete an IPC message
@@ -69,65 +69,73 @@
 
 #ifdef BTRACE_CLIENT_SERVER
 	asm("stmfd sp!,{r0,r1,ip,lr}");
-	asm("mov r2,r1");							// arg2 = aReason
-	asm("mov r1,r0");							// arg1 = aMsg
-	asm("ldr r0,_messageCompleteTraceHeader");	// arg0 = header
+	asm("mov r2,r1");															// arg2 = aReason
+	asm("mov r1,r0");															// arg1 = aMsg
+	asm("ldr r0,_messageCompleteTraceHeader");									// arg0 = header
 	asm("bl " CSM_ZN6BTrace4OutXEmmmm);
 	asm("ldmfd sp!,{r0,r1,ip,lr}");
 #endif
 
 	asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect));
 	asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession));
-	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );	// if disconnect, do it in C++
-	asm("mov r2, r1 ");					// r2=aReason
+	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );						// if disconnect, do it in C++
+
+	asm("mov r2, r1 ");															// r2 = aReason
 	ASM_DEBUG2(Complete,r0,r2);
-	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 	// r3=iSession
-	
-	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));		// (m.iFunction == RMessage2::EConnect)?
-	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));	// iSession->iConnectMsgPtr = NULL
-
-	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));	// r1=iSession->iAccessCount	
-	asm("cmp r1, #0 ");					// iAccessCount = 0?
+	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 				// r3 = iSession
+	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));						// (m.iFunction == RMessage2::EConnect)?
+	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));		// iSession->iConnectMsgPtr = NULL
+	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));				// r1 = iSession->iAccessCount	
+	asm("cmp r1, #0 ");															// iAccessCount = 0?
 	asm("beq 2f ");
 
-	// if (!s->IsClosing())
-	asm("mov r1, r0");					// r1 = RMessageK ptr
-	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    // r0=iClient
+	// !s->IsClosing()
+	asm("mov r1, r0");															// r1 = RMessageK ptr
+	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    			// r0 = iClient
+	asm("ldrb ip, [r0, #%a0] " : : "i" _FOFF(DThread,iMState));    				// ip = iClient->iMState
+	asm("cmp ip, #%a0" : : "i" (DThread::EDead));								// (iMState == EDead)?
+	asm("beq 1f ");
+
+	// if (!s->IsClosing() && m.iClient->iMState != DThread::EDead)
 	asm("mov ip, #1");
-	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));	// iServerLink.iNext=1
-	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);
+	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));		// iServerLink.iNext=1
+	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);	// tail call
 
-	// if (s->IsClosing())
+	// m.iClient->iMState == DThread::EDead
+	asm("1: ");																	// shuffle RMessageK and iFunction back to expected registers
+	asm("ldr ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// refetch iFunction
+	asm("mov r0, r1");															// r0 = RMessageK ptr
+
+	// else (closing or dead)
 	asm("2: ");
-	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));	// (m.iFunction == RMessage2::EConnect)?
-	asm("beq 4f ");
-	asm("3: ");
-	asm("stmfd sp!, {r0,lr} ");
-	asm("bl " CSM_ZN14TClientRequest5ResetEv);
-	asm("ldmfd sp!, {r0,lr} ");
-	asm("b " CSM_ZN9RMessageK8CloseRefEv);
+	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));							// (m.iFunction == RMessage2::EConnect)?
+	asm("bne 3f ");
 
-	asm("4: ");
-	// if closing & connect msg
-	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
+	// (closing or dead) and it's a connect msg
+	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
 	asm("teq r2, #0");
 #ifdef _DEBUG
 	asm("beq nosession ");
-	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));		// r1=iSession->iServer
+	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));				// r1=iSession->iServer
 	asm("cmp r1, #0 ");
  	asm("beq noserver ");
-	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));  // r2=iSession->iDisconnectMsgPtr
+	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));	// r2=iSession->iDisconnectMsgPtr
 	asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext)));	// r2=iDisconnectMsgPtr->iServerLink.iNext
 	asm("cmp r2, #0 ");
-	asm("beq __FaultMsgCompleteDiscNotSent ");	// die if a session has been created and no disc msg sent
-	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
+	asm("beq __FaultMsgCompleteDiscNotSent ");									// tail call to die if a session has been created and no disc msg sent
+	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
 	asm("noserver: ");
 	asm("teq r2, #0");
 	asm("nosession: ");
 #endif //_DEBUG
 	asm("moveq r0, r3 ");
-	asm("beq __SendDiscMsg ");	// if no session object to clean up, send disc msg in C++
-	asm("b 3b ");				// return
+	asm("beq __SendDiscMsg ");													// if no session object to clean up, tail call to send disc msg in C++
+
+	asm("3: ");
+	asm("stmfd sp!, {r0,lr} ");
+	asm("bl " CSM_ZN14TClientRequest5ResetEv);
+	asm("ldmfd sp!, {r0,lr} ");
+	asm("b " CSM_ZN9RMessageK8CloseRefEv);										// tail call
 
 #ifdef BTRACE_CLIENT_SERVER
 	asm("_messageCompleteTraceHeader:");