Is it really done when you call tevent_req_done?

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


On Sat, Jan 24, 2015 at 8:52 AM, Stefan (metze) Metzmacher
<metze at samba.org> 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
>



-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)


More information about the samba-technical mailing list