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;
|
||||
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);
|
||||
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)
|
||||
|
@ -113,6 +124,22 @@ static void disconnect(private_lookip_socket_t *this, stream_t *stream)
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -39,9 +39,8 @@ typedef stream_t*(*stream_constructor_t)(char *uri);
|
|||
/**
|
||||
* 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
|
||||
|
|
Loading…
Reference in New Issue