HI all,
Try the following:
-create a semaphore
-create a task
-let the task wait on the semaphore, no timeout
-delete the task
-delete the semaphore -> oops
The problem:
rt_task_ipc_deletes unlinks the task from the semaphores wait list, but
doesn't up the value of the semaphore
rt_sem_destroy sees a val < 0 and thus posts an event, this post then
finds nothing in the list, but it wants to run something since val < 0
so it runs nothing (NULL ptr) -> oops.
So this could be reconstructed too by:
-create semaphore
-create task
-lett task wait on semaphore
-delete task
-post to semaphore -> oops
I noticed another problem where a wait with timeout wouldn't clear the
sem_at member of the semaphore and a possible race on process deletion.
Attached is a patch fixing all these, please apply for those still using
rt_ipc.
Regards,
Hans
--- rtlinux-2.2/semaphores/rt_ipc.c.semfix Tue Dec 5 13:03:35 2000
+++ rtlinux-2.2/semaphores/rt_ipc.c Tue Dec 5 17:13:24 2000
@@ -231,6 +231,7 @@
{
/* timeout occurred -- undo everything and return */
unlink_sem_task(to_add, sem);
+ ((RT_TASK_IPC *)rtl_current)->sem_at = NULL;
++sem->val;
ret = -ETIME;
}
@@ -319,10 +320,18 @@
{
/* for task deletion safety, must remove task from any sem or mq list */
int flags;
+
+ /* suspend thread to make sure it doesn't timeout on a
+ semaphore wait after it has already been unlinked from
+ the sem linked list, but before it is deleted */
+ rt_task_suspend(MAKE_RT_TASK(task));
rtl_critical(flags);
if (task->sem_at != NULL)
+ {
unlink_sem_task(&(task->rte), task->sem_at);
+ task->sem_at->val++;
+ }
else if (task->mq_at != NULL)
unlink_mq_task(&(task->rte), task->mq_at);
rtl_end_critical(flags);