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);
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);
} else {
tee_streams_skip(tstream->tee);
}
+ /* i_stream_unref() shouldn't unref the parent */
+ tstream->istream.parent = NULL;
}
static void
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;
}
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;
}