<!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>&nbsp;</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.&nbsp;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>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>result xdb_thump(void 
*arg)<BR>{<BR>&nbsp;&nbsp;&nbsp; xdbcache xc = 
(xdbcache)arg;<BR>&nbsp;&nbsp;&nbsp; xdbcache cur, next;<BR>&nbsp;&nbsp;&nbsp; 
int now = time(NULL);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; /* spin through the cache 
looking for stale requests */<BR>&nbsp;&nbsp;&nbsp; cur = 
xc-&gt;next;<BR>&nbsp;&nbsp;&nbsp; while(cur != xc)<BR>&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next = 
cur-&gt;next;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>++++30 seconds old</FONT></DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
really old ones get wacked */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
if((now - cur-&gt;sent) &gt; 30)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
remove from ring 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
cur-&gt;prev-&gt;next = 
cur-&gt;next;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
cur-&gt;next-&gt;prev = cur-&gt;prev;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
make sure it's null as a flag for xdb_set's 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
cur-&gt;data = NULL;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
free the thread! 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
cur-&gt;preblock = 
0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
if(cur-&gt;cond != 
NULL)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pth_cond_notify(cur-&gt;cond, FALSE);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cur = 
next;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
continue;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
resend the waiting ones every so often 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((now - cur-&gt;sent) &gt; 
10)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
xdb_deliver(xc-&gt;i, cur);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* cur 
could have been free'd already on it's thread 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cur = 
next;<BR>&nbsp;&nbsp;&nbsp; }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; return r_DONE;<BR>}</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Gets invoked by the following code:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>xdbcache xdb_cache(instance 
id)<BR>{<BR>&nbsp;&nbsp;&nbsp; xdbcache newx;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; if(id == 
NULL)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
fprintf(stderr, "Programming Error: xdb_cache() called with 
NULL\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
NULL;<BR>&nbsp;&nbsp;&nbsp; }</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; newx = pmalloco(id-&gt;p, 
sizeof(_xdbcache));<BR>&nbsp;&nbsp;&nbsp; newx-&gt;i = id; /* flags it as the 
top of the ring too */<BR>&nbsp;&nbsp;&nbsp; newx-&gt;next = newx-&gt;prev = 
newx; /* init ring */</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>++++++&nbsp;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>&nbsp;&nbsp;&nbsp; /* register the handler in the 
instance to filter out xdb results */<BR>&nbsp;&nbsp;&nbsp; 
register_phandler(id, o_PRECOND, xdb_results, (void *)newx);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</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>&nbsp;&nbsp;&nbsp; /* heartbeat to keep a watchful 
eye on xdb_cache */<BR>&nbsp;&nbsp;&nbsp; register_beat(10,xdb_thump,(void 
*)newx);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; return newx;<BR>}</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>NOTE: ++++++ are my comments</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Any insight would be great.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; Thanks</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; Glenn</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV></FONT></DIV></BODY></HTML>