While debugging a problem of http.c with libev, I found this code
in evhttp_write_buffer:

        if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
                event_del(&evcon->ev);

        event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_write, evcon);
        evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_WRITE_TIMEOUT);

now, event_set initialises a struct event. the problem with the above code
is that it calls event_set on a struct event that is currently in use and
expects it to work.

this doesn't directly contradict the sparse documentation, but is rather weird.

looking at event_set closely, I see that it doesn't initialise the struct event
fully (but it does initialiseev_flags).

I also saw that some parts of the testsuite are indeed expecting that
libevent treats struct events that have never been initialised by an
event_set "properly" (= ignoring them).

I therefore conclude that there is no function in libevent that actually
initialises struct events.

This strikes me as a rather weird design, especially as it requires the user
of libevent to clear all his struct events before passing it to event_set.

It also is not threadsafe, as event_set overwrites ev_base with current_base
which might not be the correct one.

Note also that some tets programs do not properly clear the event structure
they allocate (test-time for example).

This makes me wonder about these questions:

1. could anybody confirm wether a user must clear the struct event before
   passing it to event_set?
2. shouldn't this rather fundamental requirement be documented *somewhere*?
3. is there some guarantee that one can call event_add/del on cleared memory
   arrays and this will not crash?
4. will the code fragment above not cause an event to be added twice to some
   lists, as event_set clears the flags that event_add uses to detect wether
   an event is already on the list?

In any case, I can manage in the libev emulation layer by also relying
on some "has been initialiased before" flag, but this is of course no
guarantee that code like the above will ever work (and I suspect it will
not).

In general, this whole design strikes me as rather messy.

(in libev, you always have to call one of the watcher initialiser macros
that do not depend on earlier contents).

Thanks a lot for any insights.

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      [EMAIL PROTECTED]
      -=====/_/_//_/\_,_/ /_/\_\
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users

Reply via email to