return o_stream_create(&wostream->ostream, NULL, -1);
}
-void wrapper_ostream_continue(struct wrapper_ostream *wostream)
+int wrapper_ostream_continue(struct wrapper_ostream *wostream)
{
struct ostream_private *stream = &wostream->ostream;
struct ostream *ostream = &stream->ostream;
struct ioloop *ioloop = NULL;
bool use_cork = !stream->corked;
- int ret;
+ int ret = 1;
if (wostream->flush_waiting) {
/* Inside wrapper_ostream_flush_wait() */
wostream->output != NULL &&
o_stream_get_buffer_used_size(wostream->output) == 0)) {
/* Already finished */
- if (wrapper_ostream_finish(wostream) == 0)
- return;
+ ret = wrapper_ostream_finish(wostream);
+ if (ret == 0)
+ return 0;
}
if (wostream->flush_waiting) {
i_assert(ioloop != NULL);
io_loop_stop(ioloop);
wostream->flush_waiting = FALSE;
- return;
+ return ret;
}
/* Set flush_pending = FALSE first before calling the flush callback,
if (!stream->ostream.blocking)
wrapper_ostream_output_manage(wostream, FALSE);
+ if (ret < 0 || ostream->stream_errno != 0 ||
+ wostream->pending_errno != 0)
+ ret = -1;
+ else if (wostream->output_closed)
+ ret = 1;
+ else if (!wrapper_ostream_is_empty(wostream) &&
+ (!stream->corked || wrapper_ostream_is_filled(wostream)))
+ ret = 0;
+ else if (wostream->flush_pending)
+ ret = 0;
+
o_stream_unref(&ostream);
+
+ return ret;
}
void wrapper_ostream_trigger_flush(struct wrapper_ostream *wostream)
size_t max_buffer_size, bool blocking,
struct event *event) ATTR_NULL(4);
-/* Continue sending output. */
-void wrapper_ostream_continue(struct wrapper_ostream *wostream);
+/* Continue sending output. Returns 1 if all buffered data is sent so far,
+ 0 if not, and -1 if an error occurred. */
+int wrapper_ostream_continue(struct wrapper_ostream *wostream);
/* Trigger an (asynchronous) flush on the output stream. */
void wrapper_ostream_trigger_flush(struct wrapper_ostream *wostream);