void TransactionAcquire::onTimer (bool progress, ScopedLockType& psl) { bool aggressive = false; if (getTimeouts () > 10) { WriteLog (lsWARNING, TransactionAcquire) << "Ten timeouts on TX set " << getHash (); psl.unlock(); { Application::ScopedLockType lock (getApp().getMasterLock (), __FILE__, __LINE__); if (getApp().getOPs ().stillNeedTXSet (mHash)) { WriteLog (lsWARNING, TransactionAcquire) << "Still need it"; mTimeouts = 0; aggressive = true; } } psl.lock(__FILE__, __LINE__); if (!aggressive) { mFailed = true; done (); return; } } if (aggressive || !getPeerCount ()) { // out of peers WriteLog (lsWARNING, TransactionAcquire) << "Out of peers for TX set " << getHash (); bool found = false; std::vector<Peer::pointer> peerList = getApp().getPeers ().getPeerVector (); BOOST_FOREACH (Peer::ref peer, peerList) { if (peer->hasTxSet (getHash ())) { found = true; peerHas (peer); } } if (!found) { BOOST_FOREACH (Peer::ref peer, peerList) peerHas (peer); } }
// // MFUNCTION: CPlayer::waitPdu // // PURPOSE: Wait for an incoming pdu for the // specified timeout. // If the incoming pdu has a sequence number different // from what is expected, the pdu is ignored. // // RETURN: // If a pdu arrives in time, return 0, otherwise // return Pdu_Wait_Timeout. // int CPlayer::waitPdu(Cpdu** ppPdu, DWORD timeOut, u_int16_t sequenceNumber) { int rc = 0; if (disconnected_) return CPlayer::Pdu_Wait_Timeout; long start = 0, elapsed = 0; time(&start); // note: timeOut is in milliseconds while // elapsed is in seconds while (timeOut > (1000 * elapsed)) { if (pduEvent_.lock(timeOut - (1000 * elapsed))) { // When we get here we have an incoming PDU pduEvent_.resetEvent(); // Get all pdus from queue, consider the one // with correct sequence number while (Cpdu* pdu = getFromQueue()) { // if sequence numbers don't match, ignore // the pdu and wait for next one to arrive if (checkSequenceNumber(pdu, sequenceNumber)) { // XXX Tournament: pdu received, reset timeouts setTimeouts(0); *ppPdu = pdu; return 0; // OK! } else { // pdu had wrong sequence number - it is // and old pdu and is ignored delete pdu; // The loop will check for more pdus and // will resume waiting if necessary } } long now = 0; time(&now); elapsed += (now - start); } else { // Wait timed out, will exit loop elapsed = (1000 * timeOut); } } // this is ok, player did not respond within timeout printf("CPlayer::waitPdu: timed out (%s)\n", getUsername()); rc = CPlayer::Pdu_Wait_Timeout; // XXX Tournament if (CTournament::Inst()->isTournament()) { CpduPing p; if (p.sendPing(this) == -1) { char buf[200]; sprintf(buf, "Player %s sendPing==-1\n", getUsername()); Sys_LogError(buf); setSendError(true); } setTimeouts(getTimeouts() + 1); if (getTimeouts() >= MAX_TIMEOUTS) { // Player is not responding - set network error flag char buf[200]; sprintf(buf, "Player %s (%d) times out\n", getUsername(), getConnfd()); Sys_LogError(buf); setSendError(true); } } return rc; }