Setting a task handle to NULL before it is deleted

Hello. I am curious about the safety of an operation i’m doing. I have two tasks A and B. Task A spawns task B and later deletes it by posting a notification to the task. It is done this way and not directly with vTaskDelete(taskBHandle) as task B should finish the work it is doing before being deleted. I want to make sure two instances of task B can never be running at once, and so I check whether taskBHandle is NULL before creating the task. It goes like this: Task A, on deleting task B: … if(taskBHandle != NULL) { xTaskNotifyGive(taskBHandle); taskBHandle = NULL; } TaskB: if( ulTaskNotifyTake(pdTRUE, 0) > 0) { vTaskDelete(NULL); } This seems to work just fine, but is it safe? B’s task handle is NULL when it deletes itself. Does task B hold a copy of this handle or could this cause issues?

Setting a task handle to NULL before it is deleted

I presume taskBHandle is a variable that was set when you created the task. As such, it is just a copy of the handle, not really the handle. Handles are in fact opaque pointers to the task’s TCB, so deleting the pointer to the TCB does not delete the TCB. You need to be careful of race conditions here though. If the task being deleted is guaranteed to be deleted before taskBHandle is set to NULL then it must have a higher priority than TaskA, and be waiting on the notification rather than waiting on any other object. Also, if a task deletes itself, then the memory it occupied won’t actually get deleted until the idle task runs and cleans it up (that is how all tasks used to be deleted until recent versions, so may apply to all tasks depending on the FreeRTOS version you are using). You could potentially define the portCLEANUPTCB(xHandle) macro (see where it is called from in tasks.c) to know when the task is actually gone – you would have to compare xHandle against taskBHandle to know it was the same task – but even then the macro is called immediately before the memory is freed – another task will not run until that has happened but don’t reuse the handle inside portCLEANUPTCB() itself. This is getting into ‘expert user’ territory. Alternatively, if this is the only task that is being created and deleted in your system, you could uxTaskGetNumberOfTasks() to see how many tasks there are – it will go up by one when you create the task and down by one when you delete it again.

Setting a task handle to NULL before it is deleted

I figured I could run into race conditions like that. I’l see if I can find a cleaner way to do this. Thanks for the swift reply!