From: Pekka Riikonen Date: Fri, 18 May 2007 18:14:27 +0000 (+0000) Subject: Do not uninitialize u.m.thread atomic in in finish but in free. X-Git-Tag: silc.client.1.1.beta5~9 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=ade9c1a4c12fb0b9be079605ceff7386cf420342 Do not uninitialize u.m.thread atomic in in finish but in free. Fixed Symbian wakeup synchronization. --- diff --git a/CHANGES b/CHANGES index 2ab7eafa..4725f4df 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +Fri May 18 21:10:38 EEST 2007 Pekka Riikonen + + * Do not uninitialize u.m.threads atomic int in finish but in + free. Fixes crash on any platform using atomic operations + using mutexes (like Symbian). Affected file is + lib/silcutil/silcfsm.c. + + * Fixes Symbian scheduler wakeup synchronization. Affected file + is lib/silcutil/symbian/silcsymbianscheduler.c. + Fri May 18 18:10:36 EEST 2007 Pekka Riikonen * Fixed nickname formatting to handle already formatted nicknames diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index 5139c0cd..f22540cd 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -151,6 +151,9 @@ SILC_TASK_CALLBACK(silc_fsm_free_final) if (f->thread && f->u.t.event) silc_fsm_event_free(f->u.t.event); + if (!f->thread) + silc_atomic_uninit32(&f->u.m.threads); + silc_free(f); } @@ -485,7 +488,6 @@ SILC_TASK_CALLBACK(silc_fsm_finish_fsm) silc_mutex_free(fsm->u.m.lock); fsm->u.m.lock = NULL; } - silc_atomic_uninit32(&fsm->u.m.threads); /* Call the destructor callback. */ if (fsm->destructor) diff --git a/lib/silcutil/symbian/silcsymbianscheduler.cpp b/lib/silcutil/symbian/silcsymbianscheduler.cpp index fd131024..c61af404 100644 --- a/lib/silcutil/symbian/silcsymbianscheduler.cpp +++ b/lib/silcutil/symbian/silcsymbianscheduler.cpp @@ -94,7 +94,7 @@ public: Cancel(); } - /* Wakeup */ + /* Wakeup. This is called with scheduler locked. */ void Wakeup(TThreadId thread_id) { if (wake_signal) @@ -113,6 +113,9 @@ public: { SILC_LOG_DEBUG(("Wakeup scheduler")); + /* We need to synchronize with calls to Wakeup() */ + silc_mutex_lock(schedule->lock); + /* Wakeup scheduler */ timer->Cancel(); timer->After(0); @@ -120,16 +123,19 @@ public: iStatus = KRequestPending; SetActive(); + + silc_mutex_unlock(schedule->lock); } virtual void DoCancel() { - + wake_signal = TRUE; } RThread thread; TThreadId id; SilcSymbianScheduler *timer; + SilcSchedule schedule; unsigned int wake_signal : 1; }; @@ -159,6 +165,7 @@ void silc_schedule(SilcSchedule schedule) internal->wakeup->id = RThread().Id(); internal->wakeup->thread.Open(internal->wakeup->id); internal->wakeup->timer = internal->timer; + internal->wakeup->schedule = schedule; /* Start Active Scheduler */ s->Start(); @@ -188,7 +195,7 @@ int silc_poll(SilcSchedule schedule, void *context) return 0; if (timeout == -1) - timeout = 0; + return -2; /* Set the timeout value */ at_timeout.HomeTime(); @@ -199,6 +206,8 @@ int silc_poll(SilcSchedule schedule, void *context) at_timeout += (TTimeIntervalMicroSeconds32)timeout; /* Schedule the timeout */ + if (internal->timer->IsActive()) + internal->timer->Cancel(); internal->timer->At(at_timeout); /* Return special "ignore" value. Causes the scheduler to just break @@ -279,7 +288,11 @@ void silc_schedule_internal_signals_unblock(SilcSchedule schedule, /* Nothing to do */ } +#ifdef __WINSCW__ EXPORT_C const SilcScheduleOps schedule_ops = +#else +const SilcScheduleOps schedule_ops = +#endif /* __WINSCW__ */ { silc_schedule_internal_init, silc_schedule_internal_uninit, diff --git a/lib/silcutil/symbian/silcsymbiansocketstream.cpp b/lib/silcutil/symbian/silcsymbiansocketstream.cpp index cce36443..b2362784 100644 --- a/lib/silcutil/symbian/silcsymbiansocketstream.cpp +++ b/lib/silcutil/symbian/silcsymbiansocketstream.cpp @@ -130,7 +130,8 @@ public: else s->sock->RecvFrom(inbuf, remote, 0, iStatus); - SetActive(); + if (!IsActive()) + SetActive(); } /* Reading callback */