Is it really done when you call tevent_req_done?
Stefan (metze) Metzmacher
metze at samba.org
Sat Jan 24 09:52:30 MST 2015
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
2. when tevent_req_defer_callback() was called.
In these cases a tevent_immediate event will retry
to trigger the callback.
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...
metze
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20150124/22aada38/attachment.pgp>
More information about the samba-technical
mailing list