+ silc_list_del(t->queue, q);
+ silc_list_add(t->free_queue, q);
+ silc_mutex_unlock(lock);
+ goto execute;
+ }
+
+ silc_mutex_unlock(lock);
+ silc_mutex_lock(tp->lock);
+
+ /* Nothing to do. Attempt to steal call from some other thread. */
+ o = silc_list_get(tp->threads);
+ if (!o) {
+ /* List wraps around */
+ silc_list_start(tp->threads);
+ o = silc_list_get(tp->threads);
+ }
+
+ /* Check that the other thread is valid and has something to execute. */
+ silc_mutex_lock(o->lock);
+ if (o == t || o->stop || silc_list_count(o->queue) == 0) {
+ silc_mutex_unlock(o->lock);
+ o = NULL;
+ }
+
+ if (o) {
+ silc_mutex_unlock(tp->lock);
+ silc_list_start(o->queue);
+ q = silc_list_get(o->queue);
+
+ SILC_LOG_DEBUG(("Execute call from queue from thread %p", o));
+
+ /* Execute this call now */
+ t->run = q->run;
+ t->run_context = q->run_context;
+ t->completion = q->completion;
+ t->completion_context = q->completion_context;
+ t->schedule = q->schedule;
+
+ silc_list_del(o->queue, q);
+ silc_list_add(o->free_queue, q);
+ silc_mutex_unlock(o->lock);
+ goto execute;
+ }
+
+ silc_mutex_lock(lock);
+ if (t->stop) {
+ silc_mutex_unlock(tp->lock);
+ goto stop;
+ }
+
+ /* Now that we have the lock back, check the queue again. */
+ if (silc_list_count(t->queue) > 0) {
+ silc_mutex_unlock(tp->lock);
+ goto execute_queue;