lookip: Disconnect asynchronously to avoid dead-locking watcher unregistration
While it really would be desirable to allow stream destruction during on_read()
callbacks, this does not work anymore since e49b2998
. Until we have a proper
solution for this issue, use asynchronous disconnects for the only user doing
so.
Fixes #518.
This commit is contained in:
parent
1f9e4d029e
commit
961409b668
|
@ -87,10 +87,21 @@ static void entry_destroy(entry_t *entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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;
|
enumerator_t *enumerator;
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
|
|
||||||
|
@ -98,7 +109,7 @@ static void disconnect(private_lookip_socket_t *this, stream_t *stream)
|
||||||
enumerator = this->connected->create_enumerator(this->connected);
|
enumerator = this->connected->create_enumerator(this->connected);
|
||||||
while (enumerator->enumerate(enumerator, &entry))
|
while (enumerator->enumerate(enumerator, &entry))
|
||||||
{
|
{
|
||||||
if (entry->stream == stream)
|
if (entry->stream == data->stream)
|
||||||
{
|
{
|
||||||
this->connected->remove_at(this->connected, enumerator);
|
this->connected->remove_at(this->connected, enumerator);
|
||||||
if (entry->up || entry->down)
|
if (entry->up || entry->down)
|
||||||
|
@ -113,6 +124,22 @@ static void disconnect(private_lookip_socket_t *this, stream_t *stream)
|
||||||
this->mutex->unlock(this->mutex);
|
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 for listener up/down events
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -39,9 +39,8 @@ typedef stream_t*(*stream_constructor_t)(char *uri);
|
||||||
/**
|
/**
|
||||||
* Callback function prototype, called when stream is ready.
|
* Callback function prototype, called when stream is ready.
|
||||||
*
|
*
|
||||||
* It is allowed to destroy the stream during the callback, but only if it has
|
* It is not allowed to destroy the stream nor to call on_read()/on_write/()
|
||||||
* no other active on_read()/on_write() callback and returns FALSE. It is not
|
* during the callback.
|
||||||
* allowed to to call on_read()/on_write/() during the callback.
|
|
||||||
*
|
*
|
||||||
* As select() may return even if a read()/write() would actually block, it is
|
* 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
|
* recommended to use the non-blocking calls and handle return values
|
||||||
|
|
Loading…
Reference in New Issue