Hi again,

Okay, I think I may have found the problem.  When sendmsg() (in
transmit()) returns -1 (EAGAIN - write will block), the update_event()
function encounters a segmentation fault when calling event_add().
This is probably because the previous call of event_base_set() passed
in an invalid pointer.  The code assumes that event.ev_base will
contain a valid pointer to the event base assigned to the event by a
previous call to either event_base_set() or event_add().  Maybe the
behavior pertaining to this internal event member changed?  Here is
sample code compiled against libevent-1.4.12:

#include <sys/types.h>
#include <stdio.h>
#include <event.h>

static void event_handler(const int fd, const short which, void * arg)
{ }

int
main()
{
        struct event_base               *eb;
        struct event                    ev;

        eb = event_init();

        ev.ev_base = NULL;

        printf("event_base: %p\n", (void *) eb);
        printf("event.ev_base: %p\n", (void *) ev.ev_base);

        event_set(&ev, 1, EV_WRITE | EV_PERSIST, event_handler, NULL);

        event_base_set(eb, &ev);
        printf("event.ev_base (event_base_set): %p\n", (void *)
ev.ev_base);

        event_add(&ev, 0);
        printf("event.ev_base (event_add): %p\n", (void *)
ev.ev_base);
}

It generates the following output:

event_base: 0x804b008
event.ev_base: (nil)
event.ev_base (event_base_set): (nil)
event.ev_base (event_add): (nil)

(note how the pointer value never changes)

The problem seems to have been resolved after applying the following
patch:

*** memcached-1.4.0/memcached.c Thu Jul  9 13:16:24 2009
--- memcached-1.4.0-patch/memcached.c   Wed Jul 29 12:04:04 2009
***************
*** 329,334 ****
--- 329,336 ----
          }
          MEMCACHED_CONN_CREATE(c);

+         c->event_base = base;
+
          c->rbuf = c->wbuf = 0;
          c->ilist = 0;
          c->suffixlist = 0;
***************
*** 3027,3033 ****
  static bool update_event(conn *c, const int new_flags) {
      assert(c != NULL);

!     struct event_base *base = c->event.ev_base;
      if (c->ev_flags == new_flags)
          return true;
      if (event_del(&c->event) == -1) return false;
--- 3029,3035 ----
  static bool update_event(conn *c, const int new_flags) {
      assert(c != NULL);

!     struct event_base *base = c->event_base;
      if (c->ev_flags == new_flags)
          return true;
      if (event_del(&c->event) == -1) return false;
diff -crB memcached-1.4.0/memcached.h memcached-1.4.0-patch/
memcached.h
*** memcached-1.4.0/memcached.h Thu Jul  9 13:16:24 2009
--- memcached-1.4.0-patch/memcached.h   Wed Jul 29 12:04:36 2009
***************
*** 316,321 ****
--- 316,322 ----
      enum conn_states  state;
      enum bin_substates substate;
      struct event event;
+     struct event_base *event_base;
      short  ev_flags;
      short  which;   /** which events were just triggered */

Hope this thread helps someone else.  Is this the proper channel to
report a possible bug to the memcached team?  If not, can someone
point me to the right channel.

Thanks,
thom

Reply via email to