112 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::Destruct %O",this)); |
112 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::Destruct %O",this)); |
113 __NK_ASSERT_DEBUG(((TUint)iNThread.iUserModeCallbacks & ~3) == NULL); |
113 __NK_ASSERT_DEBUG(((TUint)iNThread.iUserModeCallbacks & ~3) == NULL); |
114 iTls.Close(); |
114 iTls.Close(); |
115 if (iSyncMsgPtr) |
115 if (iSyncMsgPtr) |
116 { |
116 { |
117 __KTRACE_OPT(KSERVER,Kern::Printf("DThread::Destruct(%08X) freeing sync message at %08X", this, iSyncMsgPtr)); |
117 // The sync message might still be outstanding; in particular it may be |
118 iSyncMsgPtr->ReleaseMessagePool(RMessageK::ESync, 1); |
118 // on the kernel server's list of messages to be cleaned up on behalf of |
|
119 // dead clients. So we only release it here if it's free; otherwise, we |
|
120 // mutate the type, so that cleanup will return it to the Global pool. |
|
121 NKern::LockSystem(); |
|
122 if (iSyncMsgPtr->IsFree()) |
|
123 { |
|
124 NKern::UnlockSystem(); |
|
125 __KTRACE_OPT(KSERVER,Kern::Printf("DThread::Destruct(%08X) releasing sync message at %08X", this, iSyncMsgPtr)); |
|
126 iSyncMsgPtr->ReleaseMessagePool(RMessageK::ESync, 1); |
|
127 } |
|
128 else |
|
129 { |
|
130 __KTRACE_OPT(KSERVER,Kern::Printf("DThread::Destruct(%08X) mutating sync message at %08X", this, iSyncMsgPtr)); |
|
131 iSyncMsgPtr->iMsgType = RMessageK::EGlobal; |
|
132 NKern::UnlockSystem(); |
|
133 } |
119 iSyncMsgPtr = NULL; |
134 iSyncMsgPtr = NULL; |
120 } |
135 } |
121 FreeSupervisorStack(); |
136 FreeSupervisorStack(); |
122 iHandles.Close(iOwningProcess); |
137 iHandles.Close(iOwningProcess); |
123 Kern::SafeClose(iExtTempObj,NULL); |
138 Kern::SafeClose(iExtTempObj,NULL); |