From: Andrew M. <rh...@us...> - 2003-03-31 09:27:52
|
Update of /cvsroot/planeshift/planeshift/src/server In directory sc8-pr-cvs1:/tmp/cvs-serv5123 Modified Files: netthread.cpp Log Message: Fixed a race condition in the server networking that could cause an unlucky client to be forever removed from the senders list. Index: netthread.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/netthread.cpp,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** netthread.cpp 30 Mar 2003 07:24:38 -0000 1.71 --- netthread.cpp 31 Mar 2003 09:27:47 -0000 1.72 *************** *** 108,115 **** --- 108,127 ---- bool NetThread::SendMessage(MsgEntry* me) { + bool sendresult; Client *client = clients.Find(me->clientnum); if (!client) return false; + /* The proper way to send a message is to add it to the queue, and then add the queue to the senders. + * If you do it the other way around the net thread may remove the queue from the senders before you add the packet. + * Yes - this has actually happened! + */ + + /* We store the result here to return as the result of this function to maintain historic functionality. + * In actuality a false response does not actually mean no data was added to the queue, just that + * not all of the data could be added. + */ + sendresult=NetBase::SendMessage(me,client->outqueue); + /** * The senders list is a list of busy queues. The SendOut() function *************** *** 117,128 **** * to check every single connection each time through. */ ! if (client->outqueue->IsEmpty()) { ! client->outqueue->IncRef(); ! if (!senders.Add (client->outqueue)) ! ERRORMSG("Senderlist Full!"); } ! return NetBase::SendMessage(me,client->outqueue); } --- 129,145 ---- * to check every single connection each time through. */ ! ! /* The senders queue does not hold a reference itself, so we have to manually add one before pushing ! * this queue on. The queue is decref'd in the network thread when it's taken out of the senders queue. ! */ ! client->outqueue->IncRef(); ! if (!senders.Add (client->outqueue)) { ! // The add failed, remove the extra reference. ! client->outqueue->DecRef(); ! ERRORMSG("Senderlist Full!"); } ! return sendresult; } |