tevent immediate events

Stefan (metze) Metzmacher metze at samba.org
Fri Mar 13 14:45:42 GMT 2009


simo schrieb:
> On Fri, 2009-03-13 at 14:54 +0100, Stefan (metze) Metzmacher wrote:
>> simo schrieb:
>>> On Fri, 2009-03-13 at 12:40 +0100, Stefan (metze) Metzmacher wrote:
>>>> Hi,
>>>>
>>>> We have some usecases for directly triggered timed events
>>>> where we can't do proper reporting of allocation errors.
>>>>
>>>> I'd like to propose to add new event class for immediately triggered
>>>> events:
>>>>
>>>> typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
>>>>                                            struct tevent_immediate *im,
>>>>                                            void *private_data);
>>>> struct tevent_immediate *tevent_allocate_immediate(TALLOC_CTX *mem_ctx);
>>>> void tevent_schedule_immediate(struct tevent_context *ctx,
>>>>                                struct tevent_immediate *im,
>>>>                                tevent_immediate_handler_t handler,
>>>>                                void *private_data);

Volker: are you fine with this interface?

>>>> The caller allocated the tevent_immediate structure once and can
>>>> then schedule() it when needed. Once the event is triggered it's
>>>> detached from the tevent_context again. The caller can reuse it later.
>>>>
>>>> if the schedule function is called while the event was still scheduled,
>>>> it will be detached from the old tevent_context and attached to the new
>>>> context.
>>> Can you please clarify better what problem are you trying to solve with
>>> this scheme?
>>> Maybe give an example that shows why tevent_add_timer does not work and
>>> how this solves the problem.
>> in tevent_queue, we use a timer event to trigger the next event.
>> currently we only do this for the first event, when it's added to the
>> queue, so we can report tevent_add_timer() returning NULL.
>> The bad thing is that we trigger the following events from deep inside
>> of the talloc destructor of the finished tevent_req. I'd like to avoid
>> that, as it would mean we have event nesting. I'd like to always
>> trigger the next request via an immediate event. That means the
>> talloc destructor of the finished request would just schedule
>> the immediate event and that should not fail as we have no way to
>> handle an error there.
>>
>> I'd also like to use the immediate events in my tsocket code
>> for triggering read and write events on virtual sockets, which don't
>> have a fd. It simplifies the code a lot, if I can use call
>> a void function to schedule the event.
>>
>> There were also a lot of other situations where I liked to have
>> a way to add immediate timers without adding a lot of logic to handle
>> possible errors in the past.
>>
>> I also thought about adding a tevent_allocate_timer()/
>> tevent_schedule_timer(), but Volker proposed to add a separate
>> class of events, as it's to confusing to have to behavior for
>> tevent_timer objects. And I like the idea to split them.
> 
> I see, it seem a very good idea, but I guess one constraint is that the
> caller must make sure to not free the immediate event in a destructor as
> well.

The immediate event will also have destructor, like the timer event
which will detach the event from the context, so the caller can free it
at any time, as for every other event.

> One more question.
> I've seen that struct tevent_fd, tevent_timer, tevent_signal share most
> of the structure, with minor differences. And I imagine tevent_immediate
> would also do that. Wouldn't it make sense to have one structure (with
> unions inside and a marker that specify what it is for) and call it
> "struct tevent_event" or something to that effect for the public API ?
> Or is there any value in exposing different types ?
> Once you have tevent_immediate I guess sometimes you may want to use the
> same handler for either immediate or timer events and having different
> prototypes for the handlers would require you to have wrappers to do
> that.

tevent_fd, tevent_timer and tevent_signal are more or less low level
interfaces and should not be mixed.

tevent_req is the higher level to call async functions, where all
callbacks have the same prototype. We have tevent_wakeup_send/recv()
for the higher level, to avoid the low level interfaces.

I planing to write a README to tevent, like the talloc_guide.txt.
I already started to do that for tsocket (not finished yet)
http://gitweb.samba.org/?p=metze/samba/wip.git;a=commitdiff;h=ca60e4eae868a43136078af95a82a419fae85735

metze

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: OpenPGP digital signature
Url : http://lists.samba.org/archive/samba-technical/attachments/20090313/c0842ae2/signature.bin


More information about the samba-technical mailing list