Rather than creating a thread to read datagrams, just set the socket to

nonblocking mode and check it before simulating.  This addresses one aspect
of the lack of synchronization on AgentList, but there are other issues...
This commit is contained in:
Andrzej Kapolka 2013-04-26 11:08:41 -07:00
parent 46041b2ed9
commit b9fdba2711
3 changed files with 43 additions and 42 deletions

View file

@ -39,8 +39,6 @@
#include <ifaddrs.h> #include <ifaddrs.h>
#endif #endif
#include <pthread.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
@ -88,10 +86,7 @@ using namespace std;
void reshape(int width, int height); // will be defined below void reshape(int width, int height); // will be defined below
void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below
unsigned char incomingPacket[MAX_PACKET_SIZE];
pthread_t networkReceiveThread;
bool stopNetworkReceiveThread = false;
int packetCount = 0; int packetCount = 0;
int packetsPerSecond = 0; int packetsPerSecond = 0;
int bytesPerSecond = 0; int bytesPerSecond = 0;
@ -429,8 +424,6 @@ void terminate () {
#ifndef _WIN32 #ifndef _WIN32
audio.terminate(); audio.terminate();
#endif #endif
stopNetworkReceiveThread = true;
pthread_join(networkReceiveThread, NULL);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -1492,14 +1485,12 @@ void key(unsigned char k, int x, int y)
} }
// Receive packets from other agents/servers and decide what to do with them! // Receive packets from other agents/servers and decide what to do with them!
void *networkReceive(void *args) void networkReceive()
{ {
sockaddr senderAddress; sockaddr senderAddress;
ssize_t bytesReceived; ssize_t bytesReceived;
unsigned char *incomingPacket = new unsigned char[MAX_PACKET_SIZE];
while (!stopNetworkReceiveThread) { while (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
packetCount++; packetCount++;
bytesCount += bytesReceived; bytesCount += bytesReceived;
@ -1524,11 +1515,6 @@ void *networkReceive(void *args)
} }
} }
delete[] incomingPacket;
pthread_exit(0);
return NULL;
}
void idle(void) { void idle(void) {
timeval check; timeval check;
gettimeofday(&check, NULL); gettimeofday(&check, NULL);
@ -1560,6 +1546,9 @@ void idle(void) {
// //
updateAvatar(deltaTime); updateAvatar(deltaTime);
// read incoming packets from network
networkReceive();
//loop through all the other avatars and simulate them... //loop through all the other avatars and simulate them...
AgentList* agentList = AgentList::getInstance(); AgentList* agentList = AgentList::getInstance();
for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
@ -1703,6 +1692,7 @@ int main(int argc, const char * argv[])
listenPort = atoi(portStr); listenPort = atoi(portStr);
} }
AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort); AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort);
AgentList::getInstance()->getAgentSocket().setBlocking(false);
gettimeofday(&applicationStartupTime, NULL); gettimeofday(&applicationStartupTime, NULL);
const char* domainIP = getCmdOption(argc, argv, "--domain"); const char* domainIP = getCmdOption(argc, argv, "--domain");
@ -1785,10 +1775,6 @@ int main(int argc, const char * argv[])
printLog("Local Voxel File loaded.\n"); printLog("Local Voxel File loaded.\n");
} }
// create thread for receipt of data via UDP
pthread_create(&networkReceiveThread, NULL, networkReceive, NULL);
printLog("Network receive thread created.\n");
glutTimerFunc(1000, Timer, 0); glutTimerFunc(1000, Timer, 0);
glutMainLoop(); glutMainLoop();

View file

@ -119,7 +119,7 @@ unsigned short loadBufferWithSocketInfo(char *addressBuffer, sockaddr *socket) {
} }
} }
UDPSocket::UDPSocket(int listeningPort) { UDPSocket::UDPSocket(int listeningPort) : blocking(true) {
init(); init();
// create the socket // create the socket
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -191,6 +191,18 @@ bool UDPSocket::init() {
return true; return true;
} }
void UDPSocket::setBlocking(bool blocking) {
this->blocking = blocking;
#ifdef _WIN32
u_long mode = blocking ? 0 : 1;
ioctlsocket(handle, FIONBIO, &mode);
#else
int flags = fcntl(handle, F_GETFL, 0);
fcntl(handle, F_SETFL, blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK));
#endif
}
// Receive data on this socket with retrieving address of sender // Receive data on this socket with retrieving address of sender
bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) { bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) {

View file

@ -23,12 +23,15 @@ class UDPSocket {
UDPSocket(int listening_port); UDPSocket(int listening_port);
~UDPSocket(); ~UDPSocket();
bool init(); bool init();
void setBlocking(bool blocking);
bool isBlocking() { return blocking; }
int send(sockaddr *destAddress, const void *data, size_t byteLength); int send(sockaddr *destAddress, const void *data, size_t byteLength);
int send(char *destAddress, int destPort, const void *data, size_t byteLength); int send(char *destAddress, int destPort, const void *data, size_t byteLength);
bool receive(void *receivedData, ssize_t *receivedBytes); bool receive(void *receivedData, ssize_t *receivedBytes);
bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes); bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes);
private: private:
int handle; int handle;
bool blocking;
}; };
bool socketMatch(sockaddr *first, sockaddr *second); bool socketMatch(sockaddr *first, sockaddr *second);