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