(s)->stream_context); \
} while(0)
-static void silc_packet_dispatch(SilcPacket packet);
+static SilcBool silc_packet_dispatch(SilcPacket packet);
static void silc_packet_read_process(SilcPacketStream stream);
static inline SilcBool silc_packet_send_raw(SilcPacketStream stream,
SilcPacketType type,
SILC_LOG_DEBUG(("Injecting packet %p to stream %p", packet, packet->stream));
silc_mutex_lock(stream->lock);
- silc_packet_dispatch(packet);
+ if (!stream->destroyed)
+ silc_packet_dispatch(packet);
silc_mutex_unlock(stream->lock);
+ silc_packet_stream_unref(stream);
}
/* Write data to the stream. Must be called with ps->lock locked. Unlocks
return;
/* Now process the data */
+ silc_packet_stream_ref(ps);
if (!remote) {
silc_packet_read_process(ps);
silc_mutex_unlock(ps->lock);
silc_packet_read_process(remote);
silc_mutex_unlock(remote->lock);
}
+ silc_packet_stream_unref(ps);
break;
default:
if (packet) {
/* Inject packet to the new stream */
packet->stream = ps;
+ silc_packet_stream_ref(ps);
silc_schedule_task_add_timeout(silc_stream_get_schedule(stream->stream),
silc_packet_stream_inject_packet, packet,
0, 0);
return TRUE;
}
-/* Dispatch packet to application. Called with stream->lock locked. */
+/* Dispatch packet to application. Called with stream->lock locked.
+ Returns FALSE if the stream was destroyed while dispatching a packet. */
-static void silc_packet_dispatch(SilcPacket packet)
+static SilcBool silc_packet_dispatch(SilcPacket packet)
{
SilcPacketStream stream = packet->stream;
SilcPacketProcess p;
stream->stream_context)))
silc_packet_free(packet);
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_dlist_start(stream->process);
stream->engine->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
}
p->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
} else {
p->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
break;
stream->engine->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
}
/* If we got here, no one wanted the packet, so drop it */
silc_packet_free(packet);
+ return stream->destroyed == FALSE;
}
/* Process incoming data and parse packets. Called with stream->lock
}
/* Dispatch the packet to application */
- silc_packet_dispatch(packet);
+ if (!silc_packet_dispatch(packet))
+ break;
}
silc_buffer_reset(&stream->inbuf);
/* Signal the waiting thread for a new packet */
silc_mutex_lock(pw->wait_lock);
- if (pw->stopped) {
+ if (silc_unlikely(pw->stopped)) {
silc_mutex_unlock(pw->wait_lock);
return FALSE;
}
/* Wait here until packet has arrived */
while (silc_list_count(pw->packet_queue) == 0) {
- if (pw->stopped) {
+ if (silc_unlikely(pw->stopped)) {
silc_mutex_unlock(pw->wait_lock);
return -1;
}