On Sun, Mar 20, 2016 at 3:55 PM, Azat Khuzhin <[email protected]> wrote: > 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? In most cases, that would be overkill, as long as the fd/socket is not overloaded, the data should go out immediately (so the data can be on the stack of the function that was trying to send it, and no 'memcpy'/malloc/data housekeeping has to happen at all)
> 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. Indeed, I know, the reason I want to use cleanup, suits my needs. > "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? No, that is indeed what I was planning to do, but I thought I was missing something, as these cleanup_cbs didn't come with deferred thingy. At the moment I'm going to do this without deferring. But I'll probably have to add that later. Btw, is there a reason why the deferral infrastructure is 'internal'? Wouldn't it be useful as an extra interface of libevent? Especially the deferral implementation of 2.1.x, where some issues with priorities where solved I understood from the documentation. Or is there a reason not to use it as a more 'generic' callback deferral infrastructure? best regards, Jan > > Regards, > Azat. > *********************************************************************** > To unsubscribe, send an e-mail to [email protected] with > unsubscribe libevent-users in the body. *********************************************************************** To unsubscribe, send an e-mail to [email protected] with unsubscribe libevent-users in the body.
