From cfbb152ac8b20cd4581fa72833b7a373de4c3bae Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 18 Feb 2007 19:55:08 +0000 Subject: [PATCH] Do not deliver event signal if waiter has gone away. --- lib/silcutil/silcfsm.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index c05efdec..aff9a77e 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 - 2006 Pekka Riikonen + Copyright (C) 2005 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -632,6 +632,9 @@ SILC_TASK_CALLBACK(silc_fsm_signal) { SilcFSMEventSignal p = context; SilcMutex lock = p->event->fsm->u.m.lock; + SilcFSM fsm; + + /* We have to check couple of things before delivering the signal. */ /* If the event value has went to zero while we've been waiting this callback, the event has been been signalled already. It can happen @@ -644,6 +647,18 @@ SILC_TASK_CALLBACK(silc_fsm_signal) silc_free(p); return; } + + /* If the waiter is not waiting anymore, don't deliver the signal */ + silc_list_start(p->event->waiters); + while ((fsm = silc_list_get(p->event->waiters))) + if (fsm == p->fsm) + break; + if (!fsm) { + silc_mutex_unlock(lock); + silc_fsm_event_unref(p->event); + silc_free(p); + return; + } silc_mutex_unlock(lock); SILC_LOG_DEBUG(("Signalled %s %p", p->fsm->thread ? "thread" : "FSM", @@ -706,7 +721,7 @@ static void silc_fsm_thread_termination_signal(SilcFSMEvent event) silc_mutex_lock(lock); silc_list_start(event->waiters); - while ((fsm = silc_list_get(event->waiters)) != SILC_LIST_END) { + while ((fsm = silc_list_get(event->waiters))) { /* Signal on thread termination. Wake up destination scheduler in case caller is a real thread. */ silc_list_del(event->waiters, fsm); -- 2.24.0