AREXPORT bool ArCentralForwarder::connectingCallOnce( double heartbeatTimeout, double udpHeartbeatTimeout, double robotBackupTimeout, double clientBackupTimeout) { ArClientBase::NonBlockingConnectReturn ret; if ((ret = myClient->internalNonBlockingConnectContinue()) == ArClientBase::NON_BLOCKING_CONTINUE) return true; else if (ret == ArClientBase::NON_BLOCKING_FAILED) { ArLog::log(ArLog::Normal, "%sCould not connect to switching client %s from %s", myPrefix.c_str(), myRobotName.c_str(), mySocket->getIPString()); return false; } else if (ret == ArClientBase::NON_BLOCKING_CONNECTED) { myState = STATE_GATHERING; myLastTcpHeartbeat.setToNow(); myLastUdpHeartbeat.setToNow(); return callOnce(heartbeatTimeout, udpHeartbeatTimeout, robotBackupTimeout, clientBackupTimeout); } else { ArLog::log(ArLog::Normal, "%sIn unknown state connecting to %s", myPrefix.c_str(), myRobotName.c_str()); return false; } }
AREXPORT bool ArCentralForwarder::startingCallOnce( double heartbeatTimeout, double udpHeartbeatTimeout, double robotBackupTimeout, double clientBackupTimeout) { myClient = new ArClientBase; myClient->enforceProtocolVersion(myEnforceProtocolVersion.c_str(), false); myClient->enforceType(myEnforceType, false); std::string name; name = "ArForwarderClient_" + myRobotName; myClient->setRobotName(name.c_str()); if (myClient->internalNonBlockingConnectStart("", 0, true, "", "", mySocket) != ArClientBase::NON_BLOCKING_CONTINUE) { ArLog::log(ArLog::Normal, "%sCould not start connect to switching client %s from %s", myPrefix.c_str(), myRobotName.c_str(), mySocket->getIPString()); return false; } myState = STATE_CONNECTING; myLastTcpHeartbeat.setToNow(); myLastUdpHeartbeat.setToNow(); return callOnce(heartbeatTimeout, udpHeartbeatTimeout, robotBackupTimeout, clientBackupTimeout); }
AREXPORT bool ArCentralForwarder::gatheringCallOnce( double heartbeatTimeout, double udpHeartbeatTimeout, double robotBackupTimeout, double clientBackupTimeout) { // if we have a heartbeat timeout make sure we've heard the // heartbeat within that range if (heartbeatTimeout >= -.00000001 && myLastTcpHeartbeat.secSince() >= 5 && myLastTcpHeartbeat.secSince() / 60.0 > heartbeatTimeout) { ArLog::log(ArLog::Normal, "%sHaven't connected in %g minutes, dropping connection", myPrefix.c_str(), heartbeatTimeout); return false; } if (!myClient->getReceivedDataList() || !myClient->getReceivedArgRetList() || !myClient->getReceivedGroupAndFlagsList()) { myClient->loopOnce(); return true; } ArLog::log(ArLog::Normal, "%Connected to switching client %s from %s", myPrefix.c_str(), myRobotName.c_str(), mySocket->getIPString()); //clientBase->logDataList(); char serverName[1024]; sprintf(serverName, "ArForwarderServer_%s", myRobotName.c_str()); myServer = new ArServerBase(false, serverName, false, "", "", false, true, false, false, false); myServer->enforceProtocolVersion(myEnforceProtocolVersion.c_str()); // there's no enforce of type here since this is the proxy for MP/ME // and such (robots don't connect here) myServer->addClientRemovedCallback(&myClientServerClientRemovedCB); ArTime startedOpening; startedOpening.setToNow(); int port; bool foundPort; std::map<int, ArTime *>::iterator usedIt; // walk through our ports starting at our starting port for (port = myStartingPort, foundPort = false; !foundPort && port < 65536; port++) { // if we've used the port in the last 2 minutes then skip it if ((usedIt = myUsedPorts->find(port)) != myUsedPorts->end() && (*usedIt).second != NULL && ((*usedIt).second->getSec() == 0 || (*usedIt).second->secSince() < 120)) { ArLog::log(ArLog::Verbose, "%sSkipping port %d", myPrefix.c_str(), port); continue; } // try to open it if (myServer->open(port, myMainServer->getOpenOnIP())) { foundPort = true; myPort = port; } } if (!foundPort) { ArLog::log(ArLog::Normal, "%s Could not find port", myPrefix.c_str()); } myServer->setUserInfo(myMainServer->getUserInfo()); std::map<unsigned int, ArClientData *>::const_iterator dIt; ArClientData *clientData; myServer->addClientRemovedCallback(&myRobotServerClientRemovedCB); myClient->addHandler("centralHeartbeat", &myNetCentralHeartbeatCB); myClient->request("centralHeartbeat", 1000); if (myClient->dataExists("identSetSelfIdentifier")) { ArNetPacket sending; sending.strToBuf("CentralServer"); myClient->requestOnce("identSetSelfIdentifier", &sending); } myLastTcpHeartbeat.setToNow(); myLastUdpHeartbeat.setToNow(); for (dIt = myClient->getDataMap()->begin(); dIt != myClient->getDataMap()->end(); dIt++) { clientData = (*dIt).second; if (myMainServer->dataHasFlag(clientData->getName(), "MAIN_SERVER_ONLY")) { ArLog::log(ArLog::Normal, "%sNot forwarding %s since it is MAIN_SERVER_ONLY", myPrefix.c_str(), clientData->getName()); continue; } else if (clientData->hasDataFlag("DO_NOT_FORWARD")) { ArLog::log(ArLog::Normal, "%sNot forwarding %s since it is DO_NOT_FORWARD", myPrefix.c_str(), clientData->getName()); continue; } else if (clientData->hasDataFlag("RETURN_NONE")) { myReturnTypes[clientData->getCommand()] = RETURN_NONE; } else if (clientData->hasDataFlag("RETURN_SINGLE")) { myReturnTypes[clientData->getCommand()] = RETURN_SINGLE; myRequestOnces[clientData->getCommand()] = new std::list<ArServerClient *>; } else if (clientData->hasDataFlag("RETURN_VIDEO")) { ArLog::log(ArLog::Normal, "%sForwarding %s that is RETURN_VIDEO", myPrefix.c_str(), clientData->getName()); myReturnTypes[clientData->getCommand()] = RETURN_VIDEO; myRequestOnces[clientData->getCommand()] = new std::list<ArServerClient *>; } else if (clientData->hasDataFlag("RETURN_VIDEO_OPTIM")) { ArLog::log(ArLog::Normal, "%sForwarding %s that is RETURN_VIDEO_OPTIM", myPrefix.c_str(), clientData->getName()); myReturnTypes[clientData->getCommand()] = RETURN_VIDEO_OPTIM; myRequestOnces[clientData->getCommand()] = new std::list<ArServerClient *>; } else if (clientData->hasDataFlag("RETURN_UNTIL_EMPTY")) { myReturnTypes[clientData->getCommand()] = RETURN_UNTIL_EMPTY; myRequestOnces[clientData->getCommand()] = new std::list<ArServerClient *>; } else if (clientData->hasDataFlag("RETURN_COMPLEX")) { ArLog::log(ArLog::Normal, "%sNot forwarding %s since it is a complex return", myPrefix.c_str(), clientData->getName()); continue; } else { ArLog::log(ArLog::Normal, "%sNot forwarding %s since it is an unknown return (data flags %s)", myPrefix.c_str(), clientData->getName(), clientData->getDataFlagsString()); continue; } setLastRequest(clientData->getCommand()); setLastBroadcast(clientData->getCommand()); myServer->addDataAdvanced( clientData->getName(), clientData->getDescription(), NULL, clientData->getArgumentDescription(), clientData->getReturnDescription(), clientData->getCommandGroup(), clientData->getDataFlagsString(), clientData->getCommand(), &myInternalRequestChangedFunctor, &myInternalRequestOnceFunctor); myClient->addHandler(clientData->getName(), &myReceiveDataFunctor); } if (myClient->dataExists("centralServerHeartbeat")) { ArNetPacket sending; myRobotHasCentralServerHeartbeat = true; myLastSentCentralServerHeartbeat.setToNow(); myClient->requestOnce("centralServerHeartbeat", &sending, true); myClient->requestOnceUdp("centralServerHeartbeat", &sending, true); } myState = STATE_CONNECTED; return callOnce(heartbeatTimeout, udpHeartbeatTimeout, robotBackupTimeout, clientBackupTimeout); }
int main (){ setup(); callOnce(); return (0); }
T& get() const { callOnce(m_onceFlag, InitPtr(m_p, m_pod)); return *m_p; }
int AtomicDecAndGet(Atomic_t &v) { callOnce(g_once, initGuard); MutexLock lock(*guard); return --v.val; }
void AtomicDec(Atomic_t &v) { callOnce(g_once, initGuard); MutexLock lock(*guard); --v.val; }
int AtomicGet(Atomic_t const &v) { callOnce(g_once, initGuard); MutexLock lock(*guard); return v.val; }
bool AtomicDecAndTest(Atomic_t &v) { callOnce(g_once, initGuard); MutexLock lock(*guard); return --v.val == 0; }