SilcBool silc_fsm_thread_wait(void *fsm, void *thread)
{
SilcFSM t = thread;
+
#if defined(SILC_DEBUG)
assert(t->thread);
#endif /* SILC_DEBUG */
+
+ if (t->finished)
+ return FALSE;
t->u.t.sema = silc_fsm_sema_alloc(t->u.t.fsm, 0);
if (!t->u.t.sema)
return FALSE;
+
+ SILC_LOG_DEBUG(("Waiting for thread %p to terminate", thread));
silc_fsm_sema_wait(t->u.t.sema, fsm);
return TRUE;
}
SilcFSM fsm;
SilcMutex lock = sema->fsm->u.m.lock;
- SILC_LOG_DEBUG(("Post thread termination semaphore %p", sema));
+ SILC_LOG_DEBUG(("Post thread terminate semaphore %p", sema));
silc_mutex_lock(lock);
*
* Macro used to wait for the `thread' to terminate. The machine or
* thread will be suspended while it is waiting for the thread to
- * terminate.
+ * terminate. If the thread to be waited has already terminated (but
+ * the context has not been freed yet), this will continue immediately
+ * to the following state without waiting.
*
* NOTES
*
***/
#define SILC_FSM_THREAD_WAIT(thread) \
do { \
- silc_fsm_thread_wait(fsm, thread); \
- return SILC_FSM_WAIT; \
+ if (silc_fsm_thread_wait(fsm, thread)) \
+ return SILC_FSM_WAIT; \
+ return SILC_FSM_CONTINUE; \
} while(0)
/****f* silcutil/SilcFSMAPI/silc_fsm_alloc