From fcee05e9f0d1b8b63fb927db44923ea22ac99dda Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 12:37:14 -0700 Subject: [PATCH] handle pinging of unknown agents in AgentList thread --- avatar/src/main.cpp | 16 +++++++--- interface/src/main.cpp | 6 ++-- shared/src/AgentList.cpp | 69 +++++++++++++++++++++++++++------------- shared/src/AgentList.h | 9 +++--- 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index c7e607d5d0..73d3a3b6ba 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -66,7 +66,7 @@ void *sendAvatarData(void *args) { timeval startTime; unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - *broadcastPacket = PACKET_HEADER_HEAD_DATA; + *broadcastPacket = PACKET_HEADER_AVATAR_SERVER; unsigned char* currentBufferPosition = NULL; @@ -78,15 +78,19 @@ void *sendAvatarData(void *args) { for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + if (avatarAgent->getLinkedData() != NULL) { + currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + } } for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), - broadcastPacket, - currentBufferPosition - broadcastPacket); + if (avatarAgent->getActiveSocket()) { + agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), + broadcastPacket, + currentBufferPosition - broadcastPacket); + } } double usecToSleep = BROADCAST_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime)); @@ -111,6 +115,7 @@ int main(int argc, char* argv[]) agentList.startDomainServerCheckInThread(); agentList.startSilentAgentRemovalThread(); + agentList.startPingUnknownAgentsThread(); sockaddr *agentAddress = new sockaddr; char *packetData = new char[MAX_PACKET_SIZE]; @@ -133,6 +138,7 @@ int main(int argc, char* argv[]) agentList.stopDomainServerCheckInThread(); agentList.stopSilentAgentRemovalThread(); + agentList.stopPingUnknownAgentsThread(); pthread_join(sendAvatarDataThread, NULL); return 0; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a6abc0cefc..588663276f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -222,9 +222,6 @@ void Timer(int extra) glutTimerFunc(1000,Timer,0); gettimeofday(&timerStart, NULL); - // Ping the agents we can see - agentList.pingAgents(); - // if we haven't detected gyros, check for them now if (!serialPort.active) { serialPort.pair(); @@ -1250,9 +1247,10 @@ int main(int argc, const char * argv[]) int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData ); #endif - // start the thread which checks for silent agents + // start the agentList threads agentList.startSilentAgentRemovalThread(); agentList.startDomainServerCheckInThread(); + agentList.startPingUnknownAgentsThread(); glutInit(&argc, (char**)argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index ae30ce6f45..8826477ea3 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -28,6 +28,7 @@ const int DOMAINSERVER_PORT = 40102; bool silentAgentThreadStopFlag = false; bool domainServerCheckinStopFlag = false; +bool pingUnknownAgentThreadStopFlag = false; pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER; int unpackAgentId(unsigned char *packedData, uint16_t *agentId) { @@ -50,6 +51,7 @@ AgentList::~AgentList() { // stop the spawned threads, if they were started stopSilentAgentRemovalThread(); stopDomainServerCheckInThread(); + stopPingUnknownAgentsThread(); } std::vector& AgentList::getAgents() { @@ -209,7 +211,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId); if (socketMatch(publicSocket, localSocket)) { - // likely debugging scenario with DS + agent on local network + // likely debugging scenario with two agents on local network // set the agent active right away newAgent.activatePublicSocket(); } @@ -222,8 +224,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port); } else if (newAgent.getType() == AGENT_TYPE_VOXEL) { newAgent.activatePublicSocket(); - } else if (newAgent.getType() == AGENT_TYPE_AVATAR_MIXER) { - newAgent.activatePublicSocket(); } std::cout << "Added agent - " << &newAgent << "\n"; @@ -256,39 +256,64 @@ void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const c } } -void AgentList::pingAgents() { - char payload[1]; - *payload = PACKET_HEADER_PING; - - for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { - if (agent->getType() == AGENT_TYPE_INTERFACE) { - if (agent->getActiveSocket() != NULL) { - // we know which socket is good for this agent, send there - agentSocket.send(agent->getActiveSocket(), payload, 1); - } else { - // ping both of the sockets for the agent so we can figure out - // which socket we can use - agentSocket.send(agent->getPublicSocket(), payload, 1); - agentSocket.send(agent->getLocalSocket(), payload, 1); - } - } - } -} - void AgentList::handlePingReply(sockaddr *agentAddress) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // check both the public and local addresses for each agent to see if we find a match // prioritize the private address so that we prune erroneous local matches if (socketMatch(agent->getPublicSocket(), agentAddress)) { agent->activatePublicSocket(); + std::cout << "Activated public socket for agent " << &*agent << "\n"; break; } else if (socketMatch(agent->getLocalSocket(), agentAddress)) { agent->activateLocalSocket(); + std::cout << "Activated local socket for agent " << &*agent << "\n"; break; } } } +void *pingUnknownAgents(void *args) { + + AgentList *agentList = (AgentList *)args; + const int PING_INTERVAL_USECS = 1 * 1000000; + + timeval lastSend; + + while (!pingUnknownAgentThreadStopFlag) { + gettimeofday(&lastSend, NULL); + + for(std::vector::iterator agent = agentList->getAgents().begin(); + agent != agentList->getAgents().end(); + agent++) { + if (agent->getType() == AGENT_TYPE_INTERFACE) { + if (agent->getActiveSocket() == NULL) { + // ping both of the sockets for the agent so we can figure out + // which socket we can use + agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1); + agentList->getAgentSocket().send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1); + } + } + } + + double usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend)); + + if (usecToSleep > 0) { + usleep(usecToSleep); + } + } + + return NULL; +} + +void AgentList::startPingUnknownAgentsThread() { + pthread_create(&pingUnknownAgentsThread, NULL, pingUnknownAgents, (void *)this); +} + +void AgentList::stopPingUnknownAgentsThread() { + pingUnknownAgentThreadStopFlag = true; + pthread_join(pingUnknownAgentsThread, NULL); +} + void *removeSilentAgents(void *args) { std::vector *agents = (std::vector *)args; double checkTimeUSecs, sleepTime; diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index 7132521407..eaecc1bf50 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -37,6 +37,7 @@ class AgentList { uint16_t lastAgentId; pthread_t removeSilentAgentsThread; pthread_t checkInWithDomainServerThread; + pthread_t pingUnknownAgentsThread; void handlePingReply(sockaddr *agentAddress); public: @@ -66,7 +67,6 @@ public: void updateAgentWithData(Agent *agent, void *packetData, int dataBytes); void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes); - void pingAgents(); char getOwnerType(); unsigned int getSocketListenPort(); @@ -74,10 +74,11 @@ public: void stopSilentAgentRemovalThread(); void startDomainServerCheckInThread(); void stopDomainServerCheckInThread(); - + void startPingUnknownAgentsThread(); + void stopPingUnknownAgentsThread(); }; -int unpackAgentId(char *packedData, uint16_t *agentId); -int packAgentId(char *packStore, uint16_t agentId); +int unpackAgentId(unsigned char *packedData, uint16_t *agentId); +int packAgentId(unsigned char *packStore, uint16_t agentId); #endif /* defined(__hifi__AgentList__) */