2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 ChildWait() - Wait for a task to finish it processing.
7 #include "exec_intern.h"
8 #include <proto/exec.h>
10 /*****************************************************************************
14 AROS_LH1(IPTR
, ChildWait
,
17 AROS_LHA(ULONG
, tid
, D0
),
20 struct ExecBase
*, SysBase
, 126, Exec
)
23 Wait for either a specific child task, or any child task to finish.
24 If you specify tid = 0, then the call will return when any child
25 task exits, otherwise it will not return until the requested task
28 Note that the tid is NOT the task control block (ie struct Task *),
29 rather it is the value of the ETask et_UniqueID field. Passing in a
30 Task pointer will cause your Task to deadlock.
32 You must call ChildFree() on the returned task before calling
33 ChildWait() again. Ie.
38 ChildFree(et->et_UniqueID);
41 tid - The UniqueID of a task.
44 Returns either the ETask structure of the child, or one of the
45 CHILD_* values on error.
47 This allows you to work out which of the children has exited.
50 This function will work correctly only for child tasks that are
51 processes created with NP_NotifyOnDeath set to TRUE.
53 Calling ChildWait() on a task that isn't your child will result in
59 Be careful with the return result of this function.
65 *****************************************************************************/
69 struct Task
*ThisTask
= GET_THIS_TASK
;
74 ChildWait() will wait for either a specific or any child task to
75 finish. We we get it we return the task unique id to the caller.
77 Firstly, are we a new-style Task?
79 if (!ThisTask
|| (ThisTask
->tc_Flags
& TF_ETASK
) == 0)
82 et
= ThisTask
->tc_UnionETask
.tc_ETask
;
85 Scanning the msgport list is unsafe, we need to Forbid().
86 Note that the Wait() below will break the Forbid() condition.
87 This is how we need it to be.
90 /* We do not return until the condition is met */
93 #if defined(__AROSEXEC_SMP__)
94 EXEC_SPINLOCK_LOCK(&et
->et_TaskMsgPort
.mp_SpinLock
, NULL
, SPINLOCK_MODE_READ
);
96 /* Check if it has returned already. This will also take the first. */
97 ForeachNode(&et
->et_TaskMsgPort
.mp_MsgList
, child
)
99 if (tid
== 0 || child
->et_UniqueID
== tid
)
101 #if defined(__AROSEXEC_SMP__)
102 EXEC_SPINLOCK_UNLOCK(&et
->et_TaskMsgPort
.mp_SpinLock
);
108 #if defined(__AROSEXEC_SMP__)
109 EXEC_SPINLOCK_UNLOCK(&et
->et_TaskMsgPort
.mp_SpinLock
);
111 /* No matching children, we have to wait */
112 SetSignal(0, SIGF_CHILD
);