On Sun, Mar 20, 2016 at 03:11:31PM +0100, Jan Heylen wrote: > On Sun, Mar 20, 2016 at 3:01 PM, Azat Khuzhin <[email protected]> wrote: > >> > bufferevent_write() just move data from user-passed to bufferevent > >> > internal, you can get internal output buffer with > >> > bufferevent_get_output() > >> > >> Ah, indeed, did think about that one in the scope of using the > >> evbuffer callbacks, but the problem remains the same at that moment: > >> once you have the bufferevent_get_output, one should not alter the > >> callbacks for the output buffer of bev. So I'm not sure what that > >> would bring me in this case? > > > > evbuffer callbacks will remain the same until free, but why do you need > > them? > I've got X bytes of userdata, scattered over Y memory parts, I add > them to one evbuffer, using the evbuffer_add_reference. > Then I use evbuffer_write to send them to the fd, until it gets a > 'wouldblock', from that point on I defer the work via a bufferevent > (bufferevent_write_buffer). > > But I want to inform the user who sends me X bytes, when these X bytes > where actually send (as one action, when they are all out). > > In first place, I was thinking on using the evbuffer callbacks, but > turns out that buffervevent_write_buffer already would call these > callbacks (as the original is buffer is drained), and the callbacks of > the buffervent's internal outbuf should not be overwritten. Also, even > with these callbacks on the internal output buffer of bufferevent, it > wouldn't help probably, as 'other data' is also there, so how would > you keep track of the right data.
Actually you can add callbacks for bufferevent_get_output(), and libevent won't free them until bufferevent exist, so it can be used, but yeah cleanup_cb callback is more suitable for this case. And also quoting your original email: > some background: > * using (tcp) sockets > * sending data over the socket: in first place try to write > (evbuffer_write), if you get 'wouldblock' postpone the write by using > bufferevent_write_buffer. Main reason is we don't need to keep the > user's data in most cases and the dat is send immediatly. > * after sending data, a 'send cb' should be called to the user who > wanted to send something. Why do you need this special case evbuffer_write(), can you just use bufferevent_write_buffer() always? And in case you don't call evbuffer_write() manually your must be good. > Now, when looking at the best way to get the cleanup happening (and a > mechanism to let the user know his data is send), I was looking at > both evbuffer callbacks and the evbuffer cleanup_cb. > I'm thinking on using the cleanup_cb, as it is only called when the > chain, the actual data, gets freed, so I can be sure the data is out. > With evbuffer callbacks, the original evbuffer gets drained upon call > to bufferevent_write_buffer already, and not when the data itself is > really 'out', so that means, I have to make a distinction. Since cleanup_cb must be called only when reference didn't exist, example: struct evbuffer *buf = evbuffer_new(); evbuffer_add_reference(buf, data, len, cleanup, buf); bufferevent_write_buffer(evbuf, buf); evbuffer_free(buf); And during this calls "cleanup" will not be called because bufferevent_write_buffer() will take the chain ownership (part of evbuffer that contains you reference), so when you call evbuffer_free() there is no chain in evbuffer so "cleanup" will not be called yet. "cleanup" will be called only when it will be drained from bufferevent_get_output() and it will happen only it will be written to the client, or I'm missing something and it doesn't work like this? Regards, Azat. *********************************************************************** To unsubscribe, send an e-mail to [email protected] with unsubscribe libevent-users in the body.
