<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 5.50.4919.2200" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>
<DIV><FONT face=Arial size=2>Hi All,</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I am running jabber 1.4.2, not the latest from cvs
but fairly new. I have a test application which in an async manner logs into a
jabber server. Async meaning that if I give this app 200 users too login as it
doesn't do the logins in a linear manner, it is a state machine so any user can
be in any state of login at any time during the login process. During the
login I get a segfault in xdb_thump because it is trying to remove an entry from
the linked list that is already gone (I assume due to the state of the login).
Problem code I believe:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>result xdb_thump(void
*arg)<BR>{<BR> xdbcache xc =
(xdbcache)arg;<BR> xdbcache cur, next;<BR>
int now = time(NULL);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> /* spin through the cache
looking for stale requests */<BR> cur =
xc->next;<BR> while(cur != xc)<BR>
{<BR> next =
cur->next;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>++++30 seconds old</FONT></DIV>
<DIV><FONT face=Arial size=2> /*
really old ones get wacked */<BR>
if((now - cur->sent) > 30)<BR>
{<BR> /*
remove from ring
*/<BR>
cur->prev->next =
cur->next;<BR>
cur->next->prev = cur->prev;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial
size=2> /*
make sure it's null as a flag for xdb_set's
*/<BR>
cur->data = NULL;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial
size=2> /*
free the thread!
*/<BR>
cur->preblock =
0;<BR>
if(cur->cond !=
NULL)<BR>
pth_cond_notify(cur->cond, FALSE);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial
size=2> cur =
next;<BR>
continue;<BR> }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> /*
resend the waiting ones every so often
*/<BR> if((now - cur->sent) >
10)<BR>
xdb_deliver(xc->i, cur);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> /* cur
could have been free'd already on it's thread
*/<BR> cur =
next;<BR> }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> return r_DONE;<BR>}</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Gets invoked by the following code:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>xdbcache xdb_cache(instance
id)<BR>{<BR> xdbcache newx;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> if(id ==
NULL)<BR> {<BR>
fprintf(stderr, "Programming Error: xdb_cache() called with
NULL\n");<BR> return
NULL;<BR> }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> newx = pmalloco(id->p,
sizeof(_xdbcache));<BR> newx->i = id; /* flags it as the
top of the ring too */<BR> newx->next = newx->prev =
newx; /* init ring */</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>++++++ We register a handler here to handle
requests, which in the correct case removes the cache from the list</FONT></DIV>
<DIV><FONT face=Arial size=2> /* register the handler in the
instance to filter out xdb results */<BR>
register_phandler(id, o_PRECOND, xdb_results, (void *)newx);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>+++++We register a beat here to check the cache for
entries that are over 30 seconds old and remove them</FONT></DIV>
<DIV><FONT face=Arial size=2> /* heartbeat to keep a watchful
eye on xdb_cache */<BR> register_beat(10,xdb_thump,(void
*)newx);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> return newx;<BR>}</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>NOTE: ++++++ are my comments</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I believe that there is a thread handling the beat
and a different thread handling the phandler, if that is not true then my theory
is shot. If it is true then what is stopping the handler thread from removing
the same entry that the beat removed?</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Any insight would be great.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> Thanks</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>
Glenn</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV></FONT></DIV></BODY></HTML>