From: Martin Willi Date: Tue, 2 Jul 2013 12:09:45 +0000 (+0200) Subject: stream: allow async read/write callback to destroy the stream explicitly X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3390cd3e74f79576c96d199fe9d7daa25c5cfd7;p=thirdparty%2Fstrongswan.git stream: allow async read/write callback to destroy the stream explicitly --- diff --git a/src/libstrongswan/networking/streams/stream.c b/src/libstrongswan/networking/streams/stream.c index 20379fb415..b3dd7680b2 100644 --- a/src/libstrongswan/networking/streams/stream.c +++ b/src/libstrongswan/networking/streams/stream.c @@ -175,21 +175,26 @@ static void remove_watcher(private_stream_t *this) static bool watch(private_stream_t *this, int fd, watcher_event_t event) { bool keep = FALSE; + stream_cb_t cb; switch (event) { case WATCHER_READ: - keep = this->read_cb(this->read_data, &this->public); - if (!keep) + cb = this->read_cb; + this->read_cb = NULL; + keep = cb(this->read_data, &this->public); + if (keep) { - this->read_cb = NULL; + this->read_cb = cb; } break; case WATCHER_WRITE: - keep = this->write_cb(this->write_data, &this->public); - if (!keep) + cb = this->write_cb; + this->write_cb = NULL; + keep = cb(this->write_data, &this->public); + if (keep) { - this->write_cb = NULL; + this->write_cb = cb; } break; case WATCHER_EXCEPT: diff --git a/src/libstrongswan/networking/streams/stream.h b/src/libstrongswan/networking/streams/stream.h index 8cd8419c30..810514da96 100644 --- a/src/libstrongswan/networking/streams/stream.h +++ b/src/libstrongswan/networking/streams/stream.h @@ -39,9 +39,9 @@ typedef stream_t*(*stream_constructor_t)(char *uri); /** * Callback function prototype, called when stream is ready. * - * It is not allowed to destroy the stream during the callback, this would - * deadlock. Instead, return FALSE to destroy the stream. It is not allowed - * to call on_read()/on_write() during this callback. + * 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. * * 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 @@ -49,7 +49,7 @@ typedef stream_t*(*stream_constructor_t)(char *uri); * * @param data data passed during callback registration * @param stream associated stream - * @return FALSE to destroy the stream + * @return FALSE unregisters the invoked callback, TRUE keeps it */ typedef bool (*stream_cb_t)(void *data, stream_t *stream);