\r
/* Create the thread itself. */\r
pxThreadState->pvThread = CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE ) pxCode, pvParameters, CREATE_SUSPENDED, NULL );\r
+ configASSERT( pxThreadState->pvThread );\r
SetThreadAffinityMask( pxThreadState->pvThread, 0x01 );\r
SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );\r
SetThreadPriority( pxThreadState->pvThread, THREAD_PRIORITY_IDLE );\r
{\r
xThreadState *pxThreadState;\r
\r
- WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
+ /* Find the handle of the thread being deleted. */\r
+ pxThreadState = ( xThreadState * ) ( *( unsigned long *) pvTaskToDelete );\r
+\r
+ /* Check that the thread is still valid, it might have been closed by\r
+ vPortCloseRunningThread() - which will be the case if the task associated\r
+ with the thread originally deleted itself rather than being deleted by a\r
+ different task. */\r
+ if( pxThreadState->pvThread != NULL )\r
+ {\r
+ WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
+\r
+ CloseHandle( pxThreadState->pvThread );\r
+ TerminateThread( pxThreadState->pvThread, 0 );\r
+\r
+ ReleaseMutex( pvInterruptEventMutex );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortCloseRunningThread( void *pvTaskToDelete, volatile portBASE_TYPE *pxPendYield )\r
+{\r
+xThreadState *pxThreadState;\r
+void *pvThread;\r
\r
/* Find the handle of the thread being deleted. */\r
pxThreadState = ( xThreadState * ) ( *( unsigned long *) pvTaskToDelete );\r
- TerminateThread( pxThreadState->pvThread, 0 );\r
+ pvThread = pxThreadState->pvThread;\r
+\r
+ /* Raise the Windows priority of the thread to ensure the FreeRTOS scheduler\r
+ does not run and swap it out before it is closed. If that were to happen\r
+ the thread would never run again and effectively be a thread handle and\r
+ memory leak. */\r
+ SetThreadPriority( pvThread, THREAD_PRIORITY_ABOVE_NORMAL );\r
+\r
+ /* This function will not return, therefore a yield is set as pending to\r
+ ensure a context switch occurs away from this thread on the next tick. */\r
+ *pxPendYield = pdTRUE;\r
+\r
+ /* Mark the thread associated with this task as invalid so \r
+ vPortDeleteThread() does not try to terminate it. */\r
+ pxThreadState->pvThread = NULL;\r
\r
- ReleaseMutex( pvInterruptEventMutex );\r
+ /* Close the thread. */\r
+ CloseHandle( pvThread );\r
+ ExitThread( 0 );\r
}\r
/*-----------------------------------------------------------*/\r
\r