From d389dc6e3ad73ece5fa78f6835a0a41d07713a83 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Jul 2013 15:17:10 -0700 Subject: [PATCH] add method to NodeList to set domain IP to local, move mutex lock to node --- animation-server/src/main.cpp | 3 +- audio-mixer/src/main.cpp | 9 +++--- avatar-mixer/src/main.cpp | 3 +- interface/src/Application.cpp | 27 +++++++++++----- interface/src/Audio.cpp | 4 +-- libraries/shared/src/Node.cpp | 4 +++ libraries/shared/src/Node.h | 4 +++ libraries/shared/src/NodeList.cpp | 51 ++++++++++++++++++++----------- libraries/shared/src/NodeList.h | 22 ++++++++----- voxel-server/src/main.cpp | 3 +- 10 files changed, 85 insertions(+), 45 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 126216ea9b..c6c38d8748 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -697,8 +697,7 @@ int main(int argc, const char * argv[]) ::wantLocalDomain = cmdOptionExists(argc, argv,local); if (::wantLocalDomain) { printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + nodeList->setDomainIPToLocalhost(); } nodeList->linkedDataCreateCallback = NULL; // do we need a callback? diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index b900c48479..239eb7a32d 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -70,16 +70,15 @@ bool wantLocalDomain = false; int main(int argc, const char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); + NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); + // Handle Local Domain testing with the --local command line const char* local = "--local"; ::wantLocalDomain = cmdOptionExists(argc, argv,local); if (::wantLocalDomain) { printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); - } - - NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); + nodeList->setDomainIPToLocalhost(); + } ssize_t receivedBytes = 0; diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index f2fd031526..b24fb7dcbc 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -60,8 +60,7 @@ int main(int argc, const char* argv[]) { const char* local = "--local"; if (cmdOptionExists(argc, argv, local)) { printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + nodeList->setDomainIPToLocalhost(); } nodeList->linkedDataCreateCallback = attachAvatarDataToNode; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 75f45e8d91..6504c2d87f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -227,14 +227,14 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : const char* domainIP = getCmdOption(argc, constArgv, "--domain"); if (domainIP) { - strcpy(DOMAIN_IP, domainIP); + NodeList::getInstance()->setDomainIP(domainIP); } // Handle Local Domain testing with the --local command line if (cmdOptionExists(argc, constArgv, "--local")) { printLog("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + + NodeList::getInstance()->setDomainIPToLocalhost(); } // Check to see if the user passed in a command line option for loading a local @@ -1101,8 +1101,14 @@ void Application::editPreferences() { QFormLayout* form = new QFormLayout(); layout->addLayout(form, 1); + const int QLINE_MINIMUM_WIDTH = 400; + + QLineEdit* domainServerHostname = new QLineEdit(QString(NodeList::getInstance()->getDomainHostname())); + domainServerHostname->setMinimumWidth(QLINE_MINIMUM_WIDTH); + form->addRow("Domain server:", domainServerHostname); + QLineEdit* avatarURL = new QLineEdit(_myAvatar.getVoxels()->getVoxelURL().toString()); - avatarURL->setMinimumWidth(400); + avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Avatar URL:", avatarURL); QSpinBox* horizontalFieldOfView = new QSpinBox(); @@ -1133,9 +1139,11 @@ void Application::editPreferences() { if (dialog.exec() != QDialog::Accepted) { return; } + QUrl url(avatarURL->text()); _myAvatar.getVoxels()->setVoxelURL(url); sendAvatarVoxelURLMessage(url); + _headCameraPitchYawScale = headCameraPitchYawScale->value(); _myAvatar.setLeanScale(leanScale->value()); _audioJitterBufferSamples = audioJitterBufferSamples->value(); @@ -1956,8 +1964,8 @@ void Application::update(float deltaTime) { //loop through all the other avatars and simulate them... NodeList* nodeList = NodeList::getInstance(); - nodeList->lock(); for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + node->lock(); if (node->getLinkedData() != NULL) { Avatar *avatar = (Avatar *)node->getLinkedData(); if (!avatar->isInitialized()) { @@ -1966,8 +1974,8 @@ void Application::update(float deltaTime) { avatar->simulate(deltaTime, NULL); avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); } + node->unlock(); } - nodeList->unlock(); // Simulate myself if (_gravityUse->isChecked()) { @@ -2456,8 +2464,10 @@ void Application::displaySide(Camera& whichCamera) { if (_renderAvatarsOn->isChecked()) { // Render avatars of other nodes NodeList* nodeList = NodeList::getInstance(); - nodeList->lock(); + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + node->lock(); + if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { Avatar *avatar = (Avatar *)node->getLinkedData(); if (!avatar->isInitialized()) { @@ -2466,8 +2476,9 @@ void Application::displaySide(Camera& whichCamera) { avatar->render(false, _renderAvatarBalls->isChecked()); avatar->setDisplayingLookatVectors(_renderLookatOn->isChecked()); } + + node->unlock(); } - nodeList->unlock(); // Render my own Avatar if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 73f971b7da..0e07f50693 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -126,8 +126,8 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o dataPacket, BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); - interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO) - .updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); + interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO).updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL + + leadingBytes); } } diff --git a/libraries/shared/src/Node.cpp b/libraries/shared/src/Node.cpp index 3fddc71ad1..a023a70326 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/shared/src/Node.cpp @@ -53,6 +53,8 @@ Node::Node(sockaddr* publicSocket, sockaddr* localSocket, char type, uint16_t no } else { _localSocket = NULL; } + + pthread_mutex_init(&mutex, 0); } Node::~Node() { @@ -60,6 +62,8 @@ Node::~Node() { delete _localSocket; delete _linkedData; delete _bytesReceivedMovingAverage; + + pthread_mutex_destroy(&mutex); } // Names of Node Types diff --git a/libraries/shared/src/Node.h b/libraries/shared/src/Node.h index de43558b7a..d61657d730 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/shared/src/Node.h @@ -65,6 +65,9 @@ public: int getPingMs() const { return _pingMs; }; void setPingMs(int pingMs) { _pingMs = pingMs; }; + + void lock() { pthread_mutex_lock(&mutex); } + void unlock() { pthread_mutex_unlock(&mutex); } static void printLog(Node const&); private: @@ -83,6 +86,7 @@ private: NodeData* _linkedData; bool _isAlive; int _pingMs; + pthread_mutex_t mutex; }; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index b4e3112768..7e34f37535 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -29,9 +29,9 @@ const char SOLO_NODE_TYPES[3] = { NODE_TYPE_VOXEL_SERVER }; -char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; -char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup -const int DOMAINSERVER_PORT = 40102; +const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES] = "root.highfidelity.io"; +const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN] = ""; // IP Address will be re-set by lookup on startup +const int DEFAULT_DOMAINSERVER_PORT = 40102; bool silentNodeThreadStopFlag = false; bool pingUnknownNodeThreadStopFlag = false; @@ -63,8 +63,10 @@ NodeList::NodeList(char newOwnerType, unsigned int newSocketListenPort) : _ownerType(newOwnerType), _nodeTypesOfInterest(NULL), _ownerID(UNKNOWN_NODE_ID), - _lastNodeID(0) { - pthread_mutex_init(&mutex, 0); + _lastNodeID(0) +{ + memcpy(_domainHostname, DEFAULT_DOMAIN_HOSTNAME, sizeof(DEFAULT_DOMAIN_HOSTNAME)); + memcpy(_domainIP, DEFAULT_DOMAIN_IP, sizeof(DEFAULT_DOMAIN_IP)); } NodeList::~NodeList() { @@ -74,8 +76,19 @@ NodeList::~NodeList() { // stop the spawned threads, if they were started stopSilentNodeRemovalThread(); - - pthread_mutex_destroy(&mutex); +} + +void NodeList::setDomainHostname(const char* domainHostname) { + memcpy(_domainHostname, domainHostname, sizeof(&domainHostname)); +} + +void NodeList::setDomainIP(const char* domainIP) { + memcpy(_domainIP, domainIP, sizeof(&domainIP)); +} + +void NodeList::setDomainIPToLocalhost() { + int ip = getLocalAddress(); + sprintf(_domainIP, "%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); } void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { @@ -112,7 +125,6 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat } void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) { - lock(); // find the avatar mixer in our node list and update the lastRecvTime from it Node* bulkSendNode = nodeWithAddress(senderAddress); @@ -149,9 +161,8 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe currentPosition += updateNodeWithData(matchingNode, packetHolder, numTotalBytes - (currentPosition - startPosition)); + } - - unlock(); } int NodeList::updateNodeWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { @@ -166,6 +177,8 @@ int NodeList::updateNodeWithData(sockaddr *senderAddress, unsigned char *packetD } int NodeList::updateNodeWithData(Node *node, unsigned char *packetData, int dataBytes) { + node->lock(); + node->setLastHeardMicrostamp(usecTimestampNow()); if (node->getActiveSocket()) { @@ -176,7 +189,11 @@ int NodeList::updateNodeWithData(Node *node, unsigned char *packetData, int data linkedDataCreateCallback(node); } - return node->getLinkedData()->parseData(packetData, dataBytes); + int numParsedBytes = node->getLinkedData()->parseData(packetData, dataBytes); + + node->unlock(); + + return numParsedBytes; } Node* NodeList::nodeWithAddress(sockaddr *senderAddress) { @@ -236,18 +253,18 @@ void NodeList::sendDomainServerCheckIn() { static bool printedDomainServerIP = false; // Lookup the IP address of the domain server if we need to - if (atoi(DOMAIN_IP) == 0) { + if (atoi(_domainIP) == 0) { struct hostent* pHostInfo; - if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) { + if ((pHostInfo = gethostbyname(_domainHostname)) != NULL) { sockaddr_in tempAddress; memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); - strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); - printLog("Domain Server: %s \n", DOMAIN_HOSTNAME); + strcpy(_domainIP, inet_ntoa(tempAddress.sin_addr)); + printLog("Domain Server: %s \n", _domainHostname); } else { printLog("Failed domain server lookup\n"); } } else if (!printedDomainServerIP) { - printLog("Domain Server IP: %s\n", DOMAIN_IP); + printLog("Domain Server IP: %s\n", _domainIP); printedDomainServerIP = true; } @@ -294,7 +311,7 @@ void NodeList::sendDomainServerCheckIn() { checkInPacketSize = packetPosition - checkInPacket; } - _nodeSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, checkInPacketSize); + _nodeSocket.send(_domainIP, DEFAULT_DOMAINSERVER_PORT, checkInPacket, checkInPacketSize); } int NodeList::processDomainServerList(unsigned char* packetData, size_t dataBytes) { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 57f8083113..20eaddc738 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -9,8 +9,10 @@ #ifndef __hifi__NodeList__ #define __hifi__NodeList__ +#include #include #include +#include #include "Node.h" #include "UDPSocket.h" @@ -30,9 +32,11 @@ const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; extern const char SOLO_NODE_TYPES[3]; -extern char DOMAIN_HOSTNAME[]; -extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup -extern const int DOMAINSERVER_PORT; +const int MAX_HOSTNAME_BYTES = 255; + +extern const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES]; +extern const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN]; // IP Address will be re-set by lookup on startup +extern const int DEFAULT_DOMAINSERVER_PORT; const int UNKNOWN_NODE_ID = -1; @@ -48,6 +52,12 @@ public: NodeListIterator begin() const; NodeListIterator end() const; + const char* getDomainHostname() const { return _domainHostname; }; + void setDomainHostname(const char* domainHostname); + + void setDomainIP(const char* domainIP); + void setDomainIPToLocalhost(); + char getOwnerType() const { return _ownerType; } uint16_t getLastNodeID() const { return _lastNodeID; } @@ -67,9 +77,6 @@ public: void clear(); - void lock() { pthread_mutex_lock(&mutex); } - void unlock() { pthread_mutex_unlock(&mutex); } - void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest); void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); @@ -103,6 +110,8 @@ private: void addNodeToList(Node* newNode); + char _domainHostname[MAX_HOSTNAME_BYTES]; + char _domainIP[INET_ADDRSTRLEN]; Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET]; int _numNodes; UDPSocket _nodeSocket; @@ -113,7 +122,6 @@ private: uint16_t _lastNodeID; pthread_t removeSilentNodesThread; pthread_t checkInWithDomainServerThread; - pthread_mutex_t mutex; void handlePingReply(sockaddr *nodeAddress); void timePingReply(sockaddr *nodeAddress, unsigned char *packetData); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 254b1d2d96..4529d34bd8 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -383,8 +383,7 @@ int main(int argc, const char * argv[]) { ::wantLocalDomain = cmdOptionExists(argc, argv,local); if (::wantLocalDomain) { printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + nodeList->setDomainIPToLocalhost(); } nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;