2 * thread.library - threading and synchronisation primitives
4 * Copyright © 2007 Robert Norris
6 * This program is free software; you can redistribute it and/or modify it
7 * under the same terms as AROS itself.
10 #include "thread_intern.h"
12 #include <exec/types.h>
13 #include <exec/tasks.h>
14 #include <proto/exec.h>
15 #include <proto/thread.h>
18 /*****************************************************************************
21 AROS_LH2(BOOL
, WaitThread
,
24 AROS_LHA(uint32_t, thread_id
, D0
),
25 AROS_LHA(void **, result
, A1
),
28 struct ThreadBase
*, ThreadBase
, 6, Thread
)
31 Blocks the current task until the requested thread exits.
34 thread_id - ID of thread to detach.
35 result - pointer to storage for the thread's return value. You can
36 pass NULL here if you don't care about the return value.
39 TRUE when the thread completed successfully. FALSE if thread could not
43 A thread cannot wait on itself. A thread cannot be waited on if it is
46 If the thread has already completed, this call returns immediately with
47 the thread result. Further calls to this function for that thread will
50 Multiple threads can wait for a thread to complete. They will all
51 be notified when the thread completes, and will all receive the result.
60 CreateThread(), CurrentThread(), DetachThread()
64 *****************************************************************************/
68 struct _Thread
*thread
;
73 if ((thread
= _getthreadbyid(thread_id
, ThreadBase
)) == NULL
)
76 ObtainSemaphore(&thread
->lock
);
78 /* can't wait for ourselves, that would be silly */
79 if (thread
->task
== FindTask(NULL
)) {
80 ReleaseSemaphore(&thread
->lock
);
84 /* can't wait on detached threads */
85 if (thread
->detached
) {
86 ReleaseSemaphore(&thread
->lock
);
90 /* we only want to wait if the thread is still running */
91 if (thread
->task
!= NULL
) {
95 ReleaseSemaphore(&thread
->lock
);
98 LockMutex(thread
->exit_mutex
);
99 WaitCondition(thread
->exit
, thread
->exit_mutex
);
100 UnlockMutex(thread
->exit_mutex
);
102 ObtainSemaphore(&thread
->lock
);
104 /* no longer waiting */
105 thread
->exit_count
--;
108 /* copy the result if the caller was interested */
110 *result
= thread
->result
;
112 /* still more threads waiting, so we're done */
113 if (thread
->exit_count
> 0) {
114 ReleaseSemaphore(&thread
->lock
);
118 /* nobody else cares about this thread */
120 /* remove it from the thread list */
121 ObtainSemaphore(&ThreadBase
->lock
);
123 ReleaseSemaphore(&ThreadBase
->lock
);
125 /* and clean it up */
126 DestroyCondition(thread
->exit
);
127 DestroyMutex(thread
->exit_mutex
);