mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
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:
parent
46041b2ed9
commit
b9fdba2711
3 changed files with 43 additions and 42 deletions
|
@ -39,8 +39,6 @@
|
|||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.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 loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below
|
||||
|
||||
|
||||
pthread_t networkReceiveThread;
|
||||
bool stopNetworkReceiveThread = false;
|
||||
|
||||
unsigned char incomingPacket[MAX_PACKET_SIZE];
|
||||
int packetCount = 0;
|
||||
int packetsPerSecond = 0;
|
||||
int bytesPerSecond = 0;
|
||||
|
@ -429,8 +424,6 @@ void terminate () {
|
|||
#ifndef _WIN32
|
||||
audio.terminate();
|
||||
#endif
|
||||
stopNetworkReceiveThread = true;
|
||||
pthread_join(networkReceiveThread, NULL);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -1492,41 +1485,34 @@ void key(unsigned char k, int x, int y)
|
|||
}
|
||||
|
||||
// Receive packets from other agents/servers and decide what to do with them!
|
||||
void *networkReceive(void *args)
|
||||
void networkReceive()
|
||||
{
|
||||
sockaddr senderAddress;
|
||||
ssize_t bytesReceived;
|
||||
unsigned char *incomingPacket = new unsigned char[MAX_PACKET_SIZE];
|
||||
|
||||
while (!stopNetworkReceiveThread) {
|
||||
if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
packetCount++;
|
||||
bytesCount += bytesReceived;
|
||||
|
||||
switch (incomingPacket[0]) {
|
||||
case PACKET_HEADER_TRANSMITTER_DATA:
|
||||
myAvatar.processTransmitterData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_VOXEL_DATA:
|
||||
case PACKET_HEADER_Z_COMMAND:
|
||||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
voxels.parseData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||
AgentList::getInstance()->processBulkAgentData(&senderAddress,
|
||||
incomingPacket,
|
||||
bytesReceived);
|
||||
break;
|
||||
default:
|
||||
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
|
||||
break;
|
||||
}
|
||||
while (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
packetCount++;
|
||||
bytesCount += bytesReceived;
|
||||
|
||||
switch (incomingPacket[0]) {
|
||||
case PACKET_HEADER_TRANSMITTER_DATA:
|
||||
myAvatar.processTransmitterData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_VOXEL_DATA:
|
||||
case PACKET_HEADER_Z_COMMAND:
|
||||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
voxels.parseData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||
AgentList::getInstance()->processBulkAgentData(&senderAddress,
|
||||
incomingPacket,
|
||||
bytesReceived);
|
||||
break;
|
||||
default:
|
||||
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] incomingPacket;
|
||||
pthread_exit(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void idle(void) {
|
||||
|
@ -1560,6 +1546,9 @@ void idle(void) {
|
|||
//
|
||||
updateAvatar(deltaTime);
|
||||
|
||||
// read incoming packets from network
|
||||
networkReceive();
|
||||
|
||||
//loop through all the other avatars and simulate them...
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
|
@ -1703,6 +1692,7 @@ int main(int argc, const char * argv[])
|
|||
listenPort = atoi(portStr);
|
||||
}
|
||||
AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort);
|
||||
AgentList::getInstance()->getAgentSocket().setBlocking(false);
|
||||
|
||||
gettimeofday(&applicationStartupTime, NULL);
|
||||
const char* domainIP = getCmdOption(argc, argv, "--domain");
|
||||
|
@ -1785,10 +1775,6 @@ int main(int argc, const char * argv[])
|
|||
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);
|
||||
glutMainLoop();
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ unsigned short loadBufferWithSocketInfo(char *addressBuffer, sockaddr *socket) {
|
|||
}
|
||||
}
|
||||
|
||||
UDPSocket::UDPSocket(int listeningPort) {
|
||||
UDPSocket::UDPSocket(int listeningPort) : blocking(true) {
|
||||
init();
|
||||
// create the socket
|
||||
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
@ -191,6 +191,18 @@ bool UDPSocket::init() {
|
|||
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
|
||||
bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) {
|
||||
|
||||
|
|
|
@ -23,12 +23,15 @@ class UDPSocket {
|
|||
UDPSocket(int listening_port);
|
||||
~UDPSocket();
|
||||
bool init();
|
||||
void setBlocking(bool blocking);
|
||||
bool isBlocking() { return blocking; }
|
||||
int send(sockaddr *destAddress, 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(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes);
|
||||
private:
|
||||
int handle;
|
||||
bool blocking;
|
||||
};
|
||||
|
||||
bool socketMatch(sockaddr *first, sockaddr *second);
|
||||
|
|
Loading…
Reference in a new issue