Discussion:
free bufferevents on all data is sent in filters chain
(too old to reply)
Artem
2014-02-06 19:42:42 UTC
Permalink
Raw Message
Greetings,
I'm trying to understand how to properly free bufferevents when all data
is finished sending using filters chain.
I.e. I have one bufferevent and bufferevent_filter on top of it. I'm
writing some data into filter, and on some event I'm deciding that all
data is sent and I want to close it. If I close it immediately with
bufferevent_free I'll loose data that is in output_buffer, but is not
sent to the client. I there is no filter I'm setting write callback and,
there I check if there is still data in output_buffer and call
bufferevent_free if it's empty. With filters it doesn't work because
filter write_callback is called when underlying buffer can accept data
AND there is data in filter buffer (BEV_NORMAL), so if there is no data
in filter buffer, but there is some in underlying buffer, it will not be
called.
To fix this there should be got_out_eof in struct
bufferevent_filtered, that should be set when bufferevent_flush is
called with EV_WRITE, after that be_filter_process_output should call
user write callback no mater what. After that in user write callback we
check if all output buffers in filters chain are empty and if yes, then
free the filter bufferent. Am I missing something?
Artem Germanov.

***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Nick Mathewson
2014-02-15 21:02:49 UTC
Permalink
Raw Message
Post by Artem
Greetings,
I'm trying to understand how to properly free bufferevents when all data is
finished sending using filters chain.
I.e. I have one bufferevent and bufferevent_filter on top of it. I'm writing
some data into filter, and on some event I'm deciding that all data is sent
and I want to close it. If I close it immediately with bufferevent_free I'll
loose data that is in output_buffer, but is not sent to the client. I there
is no filter I'm setting write callback and, there I check if there is still
data in output_buffer and call bufferevent_free if it's empty. With filters
it doesn't work because filter write_callback is called when underlying
buffer can accept data AND there is data in filter buffer (BEV_NORMAL), so
if there is no data in filter buffer, but there is some in underlying
buffer, it will not be called.
To fix this there should be got_out_eof in struct bufferevent_filtered,
that should be set when bufferevent_flush is called with EV_WRITE, after
that be_filter_process_output should call user write callback no mater what.
After that in user write callback we check if all output buffers in filters
chain are empty and if yes, then free the filter bufferent. Am I missing
something?
So, the current workaround is to free the outer bufferevent without
freeing the inner one, and then set your own callbacks on the inner
one so you can close it once it's flushed.

I think that more generally, we need a "flush and then free" call for
the various bufferevent types, possibly with a callback to invoke
before freeing. It seems to be a common request.
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.

Loading...