[GIO] Using GBufferedOutputStream
- From: Ayo <ayo blicky net>
- To: gtk-app-devel-list gnome org
- Subject: [GIO] Using GBufferedOutputStream
- Date: Thu, 7 Apr 2011 12:24:57 +0200
Hello,
I am a bit at a loss as to how GBufferedOutputStream is supposed to be
used. My aim is to have a simple high-level non-blocking
send_message() function that buffers a new message and flushes the
data on the background. A naive method of doing so could be the
following (partially-pseudo) code (assuming I understood the docs
right):
GOutputStream *out;
void on_connect() {
out = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection)));
g_buffered_output_stream_set_auto_grow(G_BUFFERED_OUTPUT_STREAM(out), TRUE);
}
void handle_flush(..) {
// close connection on error
}
void send_message(char *msg) {
// this write should neither block nor fail, since we should be
writing to a buffer and "auto-grow" is true
g_output_stream_write(out, msg, ..);
g_output_stream_flush_async(out, .., handle_flush, ..);
}
The above method assumes that send_message() is not called before the
message of a previous call has been flushed. Otherwise the later flush
would, I assume, fail because there is a pending operation on the
stream. Now suppose I would want to handle this situation and allow
send_message() to be called at any time:
void handle_flush(..) {
if(error)
report_error_and_close_connection()
else if(buffer_is_not_empty())
g_output_stream_flush_async(out, .., handle_flush, ..);
}
void send_message(char *msg) {
// this write should neither block nor fail, since we should be
writing to a buffer and "auto-grow" is true
g_output_stream_write(out, msg, ..);
if(!g_output_stream_has_pending(out))
g_output_stream_flush_async(out, .., handle_flush, ..);
}
However, there are two issues with the above solution:
- GBufferedOutputStream does not provide any method to check whether
the buffer is empty, or whether there are any outstanding bytes that
need to be flushed. This is required in handle_flush() to determine
whether a new flush is required.
- Will GBufferedOutputStream correctly handle the situation where new
data is added to the buffer while it is performing a flush operation
on the background? I've skimmed a bit through the code, but get the
impression it is not supposed to be used like this.
I also just encountered a problem with g_output_stream_write(): in
some situations, it reports to have written less bytes than I asked it
to. I had assumed this to be impossible when writing to an
auto-growing buffer. I have not investigated this problem any furher
yet, though, and have no idea whether it is related to the above
problem.
Anyway, I have the impression that I'm trying to use
GBufferedOutputStream in a way it is not supposed to be used, yet I
don't think I'm trying to do anything obscure. I could have
send_message() queue messages in a separate queue and write() them in
the background from handle_flush(), but that is rather inefficient
(many of the messages are pretty small and could be combined in a
single write()) and would probably require more code than simply
implementing my own buffer.
I keep wondering if there is no better solution to do this, and how
GBufferedOutputStream *is* supposed to be used...
Ayo.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]