tevent_thread_call_depth - Man Page

The tevent call depth tracking functions

Synopsis

Topics

The tevent queue functions

Functions

void tevent_thread_call_depth_set_callback (tevent_call_depth_callback_t f, void *private_data)
Register callback function for request/subrequest call depth / flow tracking.
void tevent_thread_call_depth_reset_from_req (struct tevent_req *req)
Reset the external call depth to the call depth of the request.

Detailed Description

The call depth tracking consists of two parts.

Part 1 - storing the depth inside each tevent request.

Each instance of 'struct tevent_req' internally stores the value of the current depth. If a new subrequest is created via tevent_req_create(), the newly created subrequest gets the value from the parent incremented by 1.

Part 2 - updating external variable with the call depth of the currently processed tevent request.

The intended use of call depth is for the trace indentation. This is done by registering the address of an external size_t variable via tevent_thread_call_depth_activate(). And the tracing code just reads it's value.

The updates happen during:

tevent_req_create()

tevent_req_notify_callback()

tevent_queue_immediate_trigger()

While 'Part 1' maintains the call depth value inside each teven request precisely, the value of the external variable depends on the call flow and can be changed after return from a function call, so it no longer matches the value of the request being processed in the current function.

struct tevent_req *foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev)
{
    struct tevent_req *req, *subreq;
    struct foo_state *state;

    // External variable has value 'X', which is the value in parent code
    // It is ok, since tracing starts often only after tevent_req_create()
    req = tevent_req_create(mem_ctx, &state, struct foo_state);

    // External variable has now value 'X + 1'
    D_DEBUG("foo_send(): the external variable has the expected value\n");

    subreq = bar_send(state, ev, ...);
    tevent_req_set_callback(subreq, foo_done, req);

    // External variable has value 'X + 1 + n', where n > 0 and n is the
    // depth reached in bar_send().
    // We want to reset it via tevent_thread_call_depth_reset_from_req(),
    // since we want the following D_DEBUG() to have the right trace
    //indentation.

    tevent_thread_call_depth_reset_from_req(req);
    // External variable has again value 'X + 1' taken from req.
    D_DEBUG("foo_send(): the external variable has the expected value\n");
    return req;
}

static void foo_done(struct tevent_req *subreq)
{
    struct tevent_req *req =
        tevent_req_callback_data(subreq,
        struct tevent_req);
    struct foo_state *state =
        tevent_req_data(req,
        struct foo_state);

    // external variable has value 'X + 1'

    D_DEBUG("foo_done(): the external variable has the expected value\n");
    status = bar_recv(subreq, state, ...)
    tevent_req_done(req);
}

NTSTATUS foo_recv(struct tevent_req *req)
{
    struct foo_state *state = tevent_req_data( req, struct foo_state);

    // external variable has value 'X' (not 'X + 1')
    // which is ok, if we consider _recv() to be an access function
    // called from the parent context

    D_DEBUG("foo_recv(): external variable has the value from parent\n");
    return NT_STATUS_OK;
}

Interface has 3 parts:

Part 1: activation/deactivation

void tevent_thread_call_depth_set_callback(f, private_data) Register a callback that can track 'call depth' and 'request flow' NULL as a function callback means deactivation.

Part 2: Mark the request (and its subrequests) to be tracked

tevent_thread_call_depth_start(struct tevent_req *req)

By default, all newly created requests have call depth set to 0. tevent_thread_call_depth_start() should be called shortly after tevent_req_create(). It sets the call depth to 1. Subrequest will have call depth 2 and so on.

Part 3: reset the external variable using value from tevent request

tevent_thread_call_depth_reset_from_req(struct tevent_req *req)

If the call depth is used for trace indentation, it might be useful to reset the external variable to the call depth of currently processed tevent request, since the ext. variable can be changed after return from a function call that has created subrequests.

THREADING

The state is thread specific, i.e. each thread can activate it and register its own external variable.

Function Documentation

void tevent_thread_call_depth_reset_from_req (struct tevent_req * req)

Reset the external call depth to the call depth of the request.

Parameters

req Request from which the call depth is reset. variable.

void tevent_thread_call_depth_set_callback (tevent_call_depth_callback_t f, void * private_data)

Register callback function for request/subrequest call depth / flow tracking.

Parameters

f External call depth and flow handling function

Author

Generated automatically by Doxygen for tevent from the source code.

Info

Version 0.9.8 tevent