]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: When istream is destroyed, it now always unrefs the parent istream if it exists.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 19 Apr 2016 09:23:54 +0000 (12:23 +0300)
committerGitLab <gitlab@git.dovecot.net>
Thu, 21 Apr 2016 16:55:56 +0000 (19:55 +0300)
This way the implementations don't have to do it themselves in their
destroy() function. This change doesn't necessarily require changing the
existing code, because if the istream implementation already unrefs the
parent it gets set to NULL so the auto-unref won't be done.

src/lib/iostream-private.h
src/lib/iostream.c
src/lib/istream-tee.c
src/lib/istream.c
src/lib/ostream.c

index cc0fc9d4a9f34b453ec2fb0ad4a589248fef46cb..d56fcf43b105efee3dde2d85cee660de49c8a6cf 100644 (file)
@@ -25,7 +25,8 @@ struct iostream_private {
 
 void io_stream_init(struct iostream_private *stream);
 void io_stream_ref(struct iostream_private *stream);
-void io_stream_unref(struct iostream_private *stream);
+bool io_stream_unref(struct iostream_private *stream);
+void io_stream_free(struct iostream_private *stream);
 void io_stream_close(struct iostream_private *stream, bool close_parent);
 void io_stream_set_max_buffer_size(struct iostream_private *stream,
                                   size_t max_size);
index dbec2d9c91217f967844dad46e2d2d0a07af0fc9..8a5e9849d2200532f4421a6c3f4ab4a778a85d9c 100644 (file)
@@ -32,16 +32,21 @@ void io_stream_ref(struct iostream_private *stream)
        stream->refcount++;
 }
 
-void io_stream_unref(struct iostream_private *stream)
+bool io_stream_unref(struct iostream_private *stream)
 {
-       const struct iostream_destroy_callback *dc;
-
        i_assert(stream->refcount > 0);
        if (--stream->refcount != 0)
-               return;
+               return TRUE;
 
        stream->close(stream, FALSE);
        stream->destroy(stream);
+       return FALSE;
+}
+
+void io_stream_free(struct iostream_private *stream)
+{
+       const struct iostream_destroy_callback *dc;
+
        if (array_is_created(&stream->destroy_callbacks)) {
                array_foreach(&stream->destroy_callbacks, dc)
                        dc->callback(dc->context);
index a436fa841ef893250aae2966505915fcd6054a1c..6462844f5eca758317155511833eb58a08e1c1f4 100644 (file)
@@ -101,6 +101,8 @@ static void i_stream_tee_destroy(struct iostream_private *stream)
        } else {
                tee_streams_skip(tstream->tee);
        }
+       /* i_stream_unref() shouldn't unref the parent */
+       tstream->istream.parent = NULL;
 }
 
 static void
index 2d70a230db798a1477501590c888913f48474dbd..1f7928be1f086b577f07661cb7de64cbf171f9e9 100644 (file)
@@ -52,7 +52,11 @@ void i_stream_unref(struct istream **stream)
                if (_stream->line_str != NULL)
                        str_free(&_stream->line_str);
        }
-       io_stream_unref(&(*stream)->real_stream->iostream);
+       if (!io_stream_unref(&(*stream)->real_stream->iostream)) {
+               if ((*stream)->real_stream->parent != NULL)
+                       i_stream_unref(&(*stream)->real_stream->parent);
+               io_stream_free(&(*stream)->real_stream->iostream);
+       }
        *stream = NULL;
 }
 
index 651b26b092dc56b8a820197c3a93e78050b084fa..afa9777564d4ba6c6787243e1235194f0943ba71 100644 (file)
@@ -85,7 +85,8 @@ void o_stream_unref(struct ostream **_stream)
                        o_stream_get_name(stream));
        }
 
-       io_stream_unref(&stream->real_stream->iostream);
+       if (!io_stream_unref(&stream->real_stream->iostream))
+               io_stream_free(&stream->real_stream->iostream);
        *_stream = NULL;
 }