]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
stream: Make sure no watcher callback is active while changing stream callbacks
authorMartin Willi <martin@revosec.ch>
Tue, 21 Jan 2014 16:36:38 +0000 (17:36 +0100)
committerMartin Willi <martin@revosec.ch>
Wed, 22 Jan 2014 14:34:53 +0000 (15:34 +0100)
When changing async callbacks on streams, we have to make sure the watcher
callback is not currently active and has temporarily disabled callbacks. This
could have been the case, as we didn't explicitly removed any pending
watcher registration if both callbacks are NULL.

By enforcing the watcher unregistration, we are sure the watcher callback is
not active and currently is not mangling the callback hooks. This should make
sure we avoid any races for the callback variables.

src/libstrongswan/networking/streams/stream.c

index 8ecb89fc96faef0ff16fefaeaacb3bb148d21af9..f6fec0b4a4d99723b07b49286fefd59ff07c951d 100644 (file)
@@ -158,17 +158,6 @@ METHOD(stream_t, write_all, bool,
        return TRUE;
 }
 
-/**
- * Remove a registered watcher
- */
-static void remove_watcher(private_stream_t *this)
-{
-       if (this->read_cb || this->write_cb)
-       {
-               lib->watcher->remove(lib->watcher, this->fd);
-       }
-}
-
 /**
  * Watcher callback
  */
@@ -228,7 +217,7 @@ static void add_watcher(private_stream_t *this)
 METHOD(stream_t, on_read, void,
        private_stream_t *this, stream_cb_t cb, void *data)
 {
-       remove_watcher(this);
+       lib->watcher->remove(lib->watcher, this->fd);
 
        this->read_cb = cb;
        this->read_data = data;
@@ -239,7 +228,7 @@ METHOD(stream_t, on_read, void,
 METHOD(stream_t, on_write, void,
        private_stream_t *this, stream_cb_t cb, void *data)
 {
-       remove_watcher(this);
+       lib->watcher->remove(lib->watcher, this->fd);
 
        this->write_cb = cb;
        this->write_data = data;
@@ -270,7 +259,7 @@ METHOD(stream_t, get_file, FILE*,
 METHOD(stream_t, destroy, void,
        private_stream_t *this)
 {
-       remove_watcher(this);
+       lib->watcher->remove(lib->watcher, this->fd);
        close(this->fd);
        free(this);
 }