}
/**
- * Disconnect a stream, remove connection entry
+ * Data for async disconnect job
*/
-static void disconnect(private_lookip_socket_t *this, stream_t *stream)
+typedef struct {
+ /** socket ref */
+ private_lookip_socket_t *this;
+ /** stream to disconnect */
+ stream_t *stream;
+} disconnect_data_t;
+
+/**
+ * Disconnect a stream asynchronously, remove connection entry
+ */
+static job_requeue_t disconnect_async(disconnect_data_t *data)
{
+ private_lookip_socket_t *this = data->this;
enumerator_t *enumerator;
entry_t *entry;
enumerator = this->connected->create_enumerator(this->connected);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->stream == stream)
+ if (entry->stream == data->stream)
{
this->connected->remove_at(this->connected, enumerator);
if (entry->up || entry->down)
this->mutex->unlock(this->mutex);
}
+/**
+ * Queue async disconnect job
+ */
+static void disconnect(private_lookip_socket_t *this, stream_t *stream)
+{
+ disconnect_data_t *data;
+
+ INIT(data,
+ .this = this,
+ .stream = stream,
+ );
+
+ lib->processor->queue_job(lib->processor,
+ (job_t*)callback_job_create(disconnect_async, data, free, NULL));
+}
+
/**
* Callback function for listener up/down events
*/
/**
* Callback function prototype, called when stream is ready.
*
- * It is allowed to destroy the stream during the callback, but only if it has
- * no other active on_read()/on_write() callback and returns FALSE. It is not
- * allowed to to call on_read()/on_write/() during the callback.
+ * It is not allowed to destroy the stream nor to call on_read()/on_write/()
+ * during the callback.
*
* As select() may return even if a read()/write() would actually block, it is
* recommended to use the non-blocking calls and handle return values