It seems there is no efficient way to change the timeout
of a persistent event?

This might be desired for example to have a different timeout
while reading bytes within a message, than a timeout between
messages on the same socket.

An alternative solution might be two have two different
timers, one intra-message and one inter-message, except
that it seems the API doesn't have an efficient way to
temporarily disable an event either.
So that doesn't really help.

It seems that all that can be done if you want to change 
a timeout is:
   event_del(&ev);
   event_add(&ev, &new_tv);

I guess this is a consequence of the choice of a RB tree
to organize the events.

an alternative approach for example would be to use an
array instead and do this for the loop:

1. sort the array if any timeouts have been added/removed since last
sort.
treated removed events as having infinite timeout, so they are moved to
the end of the array which can be used for empty space.

2. call all timout handlers for expired timers
     if any timeout handler does add or remove, don't sort, just update
     the minimum timeout value

3. call dispatch with minimum timeout value
    callbacks will do multiple adds/removes, but don't compress
   or sort array until all callbacks are done (step 1).

A benefit of the above approach is that changing the
timeout value in a persistent event doesn't affect performance
much.

Yet another choice would be a "Judy tree".

Yet another approacch that would be very fast is to take advantage
of the fact that the programmer likely doesn't care too much about
exact timeout values. Suppose that the longest timeout value to
be used is 1 minute, and the programmer doesn't care about anything
better than 5 second resolution. Then all that is needed is 12 linked
lists, one for each 5-second interval in a minute. Each list is itself
unsorted. Then every operation is very fast:
   add - push the event onto list number = timeout / 12 : O(1)
   del - remove from linked list: O(1)
   min - find first list with > 0 entries: effectively O(1)
   foreach - drain all lists up to expiration / 12 : O(1)

This is only applicable in the conditions stated, but I believe those
to be quite typical.

I guess the easiest way to do the experiment would be to override
the RB_* macros in event.c.

-mda
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users

Reply via email to