Is it really done when you call tevent_req_done?

Richard Sharpe realrichardsharpe at
Sat Jan 24 10:36:45 MST 2015

On Sat, Jan 24, 2015 at 8:52 AM, Stefan (metze) Metzmacher
<metze at> wrote:
> Hi Richard,
>> In my seemingly never ending quest to understand tevent, I noticed the
>> following in some random smb2 request processing routine, like
>> smbd_smb2_request_process_tcon:
>> ....
>>         subreq = smbd_smb2_tree_connect_send(req,
>>                                              req->sconn->ev_ctx,
>>                                              req,
>>                                              in_path_string);
>>         if (subreq == NULL) {
>>                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
>>         }
>>         tevent_req_set_callback(subreq, smbd_smb2_request_tcon_done, req);
>>         return smbd_smb2_request_pending_queue(req, subreq, 500);
>> So, we create a subrequest in smbd_smb2_tree_connect_send and if we
>> got one, we set a callback (smbd_smb2_request_tcon_done and then call
>> that routine that will queue it perhaps.
>> However, when we look at smbd_smb2_tree_connect_send we see:
>> ...
>>         status = smbd_smb2_tree_connect(smb2req,
>>                                         state->in_path,
>>                                         &state->out_share_type,
>>                                         &state->out_share_flags,
>>                                         &state->out_capabilities,
>>                                         &state->out_maximal_access,
>>                                         &state->out_tree_id);
>>         if (tevent_req_nterror(req, status)) {
>>                 return tevent_req_post(req, ev);
>>         }
>>         tevent_req_done(req);
>>         return tevent_req_post(req, ev);
>> Huh, is it done or what? Done means finito, no more to do, etc. But
>> seemingly the request has a second life because tevent_req_post is
>> going to stick it in the tevent queue and then when we get back to our
>> caller it is going to be given a callback ...
>> I am confused and starting to feel like Alice:
>> 'When I use a word,' Humpty Dumpty said, in rather a scornful tone,
>> 'it means just what I choose it to mean — neither more nor less.'
> There three layers:
> 1. The implementation e.g. all smbd_smb2_tree_connect* functions.
>    The implementation provides a _send() and a _recv() function
>    to the callers. The implementation owns the internal
>    smbd_smb2_tree_connect_state.
> 2. The tevent_req* helper functions.
> 3. The caller, it offers the memory context and event context
>    and passes them to the _send() function.  The sync caller
>    checks tevent_req_is_in_progress() is false before calling
>    the _recv() function to get the result. An async caller
>    calls the _recv() function from a registered callback function.
>    The caller owns the 'tevent_req' structure and should free it
>    after calling the _recv() function.
> So from the implementation ("smbd_smb2_tree_connect*") point of view
> the work that needs to be done is done.
> At this point tevent_req_is_in_progress()
> would return false.
> That means that the caller can ask for result by calling
> smbd_smb2_tree_connect_recv().
> In some situations tevent_req_done() (, tevent_req_notify_callback() or
> tevent_req_*error())
> doesn't call the callers callback function:
> 1. when it's called from the _send() function or

Hmmm, but that seems to be because no callback function has been
established yet via tevent_req_set_callback.

> 2. when tevent_req_defer_callback() was called.
> In these cases a tevent_immediate event will retry
> to trigger the callback.

Right, but that seems to be caused by the tevent_req_post call that is
made, and the callback is not established until we are out of the
context of the caller of tevent_req_post.

> Once the caller gets the result using the _recv() function
> it can use destroy the request by using TALLOC_FREE(subreq).
> I hope this explains it a bit...

Yes, it does. I know this stuff is cast in stone now, but the naming
of some of the helper functions obfuscates things quite a bit.

> metze

Richard Sharpe

More information about the samba-technical mailing list