From bed4819313197652518c7732e215ccf08df5361e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 24 Sep 2013 14:41:26 -0700 Subject: [PATCH] inital setup for static assignment mapped file --- domain-server/src/main.cpp | 108 +++++++++++++--------------- libraries/shared/src/Assignment.cpp | 106 +++++++++++++++++++++------ libraries/shared/src/Assignment.h | 21 +++--- 3 files changed, 143 insertions(+), 92 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 427717131d..5304b6baec 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -139,30 +140,57 @@ int main(int argc, const char* argv[]) { timeval lastStatSendTime = {}; - // as a domain-server we will always want an audio mixer and avatar mixer - // setup the create assignments for those - Assignment audioMixerAssignment(Assignment::CreateCommand, - Assignment::AudioMixerType, - Assignment::LocalLocation); + const QString STATIC_ASSIGNMENT_FILENAME = QString("%1/config.ds").arg(QCoreApplication::applicationDirPath()); - Assignment avatarMixerAssignment(Assignment::CreateCommand, - Assignment::AvatarMixerType, - Assignment::LocalLocation); + const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000; - Assignment voxelServerAssignment(Assignment::CreateCommand, - Assignment::VoxelServerType, - Assignment::LocalLocation); - - // Handle Domain/Voxel Server configuration command line arguments - const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig"; - const char* voxelServerConfig = getCmdOption(argc, argv, VOXEL_CONFIG_OPTION); - if (voxelServerConfig) { - qDebug("Reading Voxel Server Configuration.\n"); - qDebug() << " config: " << voxelServerConfig << "\n"; - int payloadLength = strlen(voxelServerConfig) + sizeof(char); - voxelServerAssignment.setPayload((const uchar*)voxelServerConfig, payloadLength); + QFile staticAssignmentFile(STATIC_ASSIGNMENT_FILENAME); + + if (!staticAssignmentFile.exists()) { + + const uint NUM_FRESH_STATIC_ASSIGNMENTS = 3; + + // write a fresh static assignment list to file + Assignment freshStaticAssignmentList[NUM_FRESH_STATIC_ASSIGNMENTS]; + + // pre-populate the first static assignment list with assignments for root AuM, AvM, VS + freshStaticAssignmentList[0] = Assignment(Assignment::CreateCommand, + Assignment::AudioMixerType, + Assignment::LocalLocation); + freshStaticAssignmentList[1] = Assignment(Assignment::CreateCommand, + Assignment::AvatarMixerType, + Assignment::LocalLocation); + + Assignment voxelServerAssignment(Assignment::CreateCommand, Assignment::VoxelServerType, Assignment::LocalLocation); + + // Handle Domain/Voxel Server configuration command line arguments + const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig"; + const char* voxelServerConfig = getCmdOption(argc, argv, VOXEL_CONFIG_OPTION); + if (voxelServerConfig) { + qDebug("Reading Voxel Server Configuration.\n"); + qDebug() << " config: " << voxelServerConfig << "\n"; + int payloadLength = strlen(voxelServerConfig) + sizeof(char); + voxelServerAssignment.setPayload((const uchar*)voxelServerConfig, payloadLength); + } + + freshStaticAssignmentList[2] = voxelServerAssignment; + + staticAssignmentFile.open(QIODevice::WriteOnly); + + staticAssignmentFile.write((char*) &NUM_FRESH_STATIC_ASSIGNMENTS, + sizeof(uint16_t)); + staticAssignmentFile.write((char*) &freshStaticAssignmentList, sizeof(freshStaticAssignmentList)); + staticAssignmentFile.resize(MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS * sizeof(Assignment)); + staticAssignmentFile.close(); } + staticAssignmentFile.open(QIODevice::ReadWrite); + + uchar* staticAssignmentFileData = staticAssignmentFile.map(0, staticAssignmentFile.size()); + + uint16_t* numAssignmentsInStaticFile = (uint16_t*) staticAssignmentFileData; + Assignment* staticFileAssignments = (Assignment*) (staticAssignmentFileData + sizeof(*numAssignmentsInStaticFile)); + // construct a local socket to send with our created assignments to the global AS sockaddr_in localSocket = {}; localSocket.sin_family = AF_INET; @@ -186,46 +214,6 @@ int main(int argc, const char* argv[]) { ctx = mg_start(&callbacks, NULL, options); while (true) { - - ::assignmentQueueMutex.lock(); - // check if our audio-mixer or avatar-mixer are dead and we don't have existing assignments in the queue - // so we can add those assignments back to the front of the queue since they are high-priority - if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER) && - std::find(::assignmentQueue.begin(), assignmentQueue.end(), &avatarMixerAssignment) == ::assignmentQueue.end()) { - qDebug("Missing an avatar mixer and assignment not in queue. Adding.\n"); - - // reset the UUID so it is new - avatarMixerAssignment.resetUUID(); - - ::assignmentQueue.push_front(&avatarMixerAssignment); - } - - if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER) && - std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &audioMixerAssignment) == ::assignmentQueue.end()) { - qDebug("Missing an audio mixer and assignment not in queue. Adding.\n"); - - // reset the UUID so it is new - audioMixerAssignment.resetUUID(); - - ::assignmentQueue.push_front(&audioMixerAssignment); - } - - // Now handle voxel servers. Since Voxel Servers aren't soloNodeOfType() we will count them and add an assignment if - // there is not at least one of them in the domain. - int voxelServerCount = 0; - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - if (node->getType() == NODE_TYPE_VOXEL_SERVER) { - voxelServerCount++; - } - } - if (voxelServerCount == 0 && - std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) { - qDebug("Missing a voxel server and assignment not in queue. Adding.\n"); - ::assignmentQueue.push_front(&voxelServerAssignment); - } - - ::assignmentQueueMutex.unlock(); - while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) && packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) { diff --git a/libraries/shared/src/Assignment.cpp b/libraries/shared/src/Assignment.cpp index 88d50aee28..400f128db9 100644 --- a/libraries/shared/src/Assignment.cpp +++ b/libraries/shared/src/Assignment.cpp @@ -9,37 +9,79 @@ #include "PacketHeaders.h" #include "SharedUtil.h" +#include + #include "Assignment.h" const char IPv4_ADDRESS_DESIGNATOR = 4; const char IPv6_ADDRESS_DESIGNATOR = 6; +Assignment::Assignment() : + _uuid(), + _command(Assignment::RequestCommand), + _type(Assignment::AllTypes), + _location(Assignment::LocalLocation), + _numberOfInstances(1), + _payload(), + _numPayloadBytes(0) +{ + +} + Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) : _command(command), _type(type), _location(location), _numberOfInstances(1), - _payload(NULL), + _payload(), _numPayloadBytes(0) { - // set the create time on this assignment - gettimeofday(&_time, NULL); - if (_command == Assignment::CreateCommand) { // this is a newly created assignment, generate a random UUID _uuid = QUuid::createUuid(); } } +Assignment::Assignment(const Assignment& otherAssignment) { + + _uuid = otherAssignment._uuid; + + _command = otherAssignment._command; + _type = otherAssignment._type; + _location = otherAssignment._location; + _numberOfInstances = otherAssignment._numberOfInstances; + + setPayload(otherAssignment._payload, otherAssignment._numPayloadBytes); +} + +Assignment& Assignment::operator=(const Assignment& rhsAssignment) { + Assignment temp(rhsAssignment); + swap(temp); + return *this; +} + +void Assignment::swap(Assignment& otherAssignment) { + using std::swap; + + swap(_uuid, otherAssignment._uuid); + swap(_command, otherAssignment._command); + swap(_type, otherAssignment._type); + swap(_location, otherAssignment._location); + swap(_numberOfInstances, otherAssignment._numberOfInstances); + + for (int i = 0; i < MAX_PAYLOAD_BYTES; i++) { + swap(_payload[i], otherAssignment._payload[i]); + } + + swap(_numPayloadBytes, otherAssignment._numPayloadBytes); +} + Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) : _location(GlobalLocation), _numberOfInstances(1), - _payload(NULL), + _payload(), _numPayloadBytes(0) -{ - // set the create time on this assignment - gettimeofday(&_time, NULL); - +{ int numBytesRead = 0; if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) { @@ -62,19 +104,10 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) : } if (numBytes > numBytesRead) { - _numPayloadBytes = numBytes - numBytesRead; - _payload = new uchar[_numPayloadBytes]; - memcpy(_payload, dataBuffer + numBytesRead, _numPayloadBytes); + setPayload(dataBuffer + numBytesRead, numBytes - numBytesRead); } } -Assignment::~Assignment() { - delete[] _payload; - _numPayloadBytes = 0; -} - -const int MAX_PAYLOAD_BYTES = 1024; - void Assignment::setPayload(const uchar* payload, int numBytes) { if (numBytes > MAX_PAYLOAD_BYTES) { @@ -87,8 +120,7 @@ void Assignment::setPayload(const uchar* payload, int numBytes) { _numPayloadBytes = numBytes; } - delete[] _payload; - _payload = new uchar[_numPayloadBytes]; + memset(_payload, 0, MAX_PAYLOAD_BYTES); memcpy(_payload, payload, _numPayloadBytes); } @@ -123,4 +155,34 @@ void Assignment::run() { QDebug operator<<(QDebug debug, const Assignment &assignment) { debug << "T:" << assignment.getType(); return debug.nospace(); -} \ No newline at end of file +} + +QDataStream& operator<<(QDataStream& out, const Assignment& assignment) { + out << assignment._uuid; + out << (uchar) assignment._command; + out << (uchar) assignment._type; + out << (uchar) assignment._location; + out << assignment._numberOfInstances; + out << assignment._numPayloadBytes; + + if (assignment._numPayloadBytes > 0) { + out.writeBytes((char*) assignment._payload, assignment._numPayloadBytes); + } + + return out; +} + +QDataStream& operator>>(QDataStream& in, Assignment& assignment) { + in >> assignment._uuid; + in >> (uchar&) assignment._command; + in >> (uchar&) assignment._type; + in >> (uchar&) assignment._location; + in >> assignment._numberOfInstances; + in >> assignment._numPayloadBytes; + + if (assignment._numPayloadBytes > 0) { + in.readRawData((char*) assignment._payload, assignment._numPayloadBytes); + } + + return in; +} diff --git a/libraries/shared/src/Assignment.h b/libraries/shared/src/Assignment.h index d861beb537..eca5baff5d 100644 --- a/libraries/shared/src/Assignment.h +++ b/libraries/shared/src/Assignment.h @@ -16,6 +16,7 @@ #include "NodeList.h" const int NUM_BYTES_RFC4122_UUID = 16; +const int MAX_PAYLOAD_BYTES = 1024; /// Holds information used for request, creation, and deployment of assignments class Assignment : public QObject { @@ -41,17 +42,20 @@ public: LocalLocation }; + Assignment(); Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location = Assignment::LocalLocation); + Assignment(const Assignment& otherAssignment); + Assignment& operator=(const Assignment &rhsAssignment); + + void swap(Assignment& otherAssignment); /// Constructs an Assignment from the data in the buffer /// \param dataBuffer the source buffer to un-pack the assignment from /// \param numBytes the number of bytes left to read in the source buffer Assignment(const unsigned char* dataBuffer, int numBytes); - ~Assignment(); - const QUuid& getUUID() const { return _uuid; } QString getUUIDStringWithoutCurlyBraces() const; void resetUUID() { _uuid = QUuid::createUuid(); } @@ -59,7 +63,6 @@ public: Assignment::Command getCommand() const { return _command; } Assignment::Type getType() const { return _type; } Assignment::Location getLocation() const { return _location; } - const timeval& getTime() const { return _time; } uchar* getPayload() { return _payload; } int getNumPayloadBytes() const { return _numPayloadBytes; } @@ -74,23 +77,21 @@ public: /// \return number of bytes packed into buffer int packToBuffer(unsigned char* buffer); - /// Sets _time to the current time given by gettimeofday - void setCreateTimeToNow() { gettimeofday(&_time, NULL); } - /// blocking run of the assignment virtual void run(); + friend QDebug operator<<(QDebug debug, const Assignment& assignment); + friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment); + friend QDataStream& operator>>(QDataStream &in, Assignment& assignment); + private: QUuid _uuid; /// the 16 byte UUID for this assignment Assignment::Command _command; /// the command for this assignment (Create, Deploy, Request) Assignment::Type _type; /// the type of the assignment, defines what the assignee will do Assignment::Location _location; /// the location of the assignment, allows a domain to preferentially use local ACs - timeval _time; /// time the assignment was created (set in constructor) int _numberOfInstances; /// the number of instances of this assignment - uchar *_payload; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed + uchar _payload[MAX_PAYLOAD_BYTES]; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed int _numPayloadBytes; /// number of bytes in the payload, up to a maximum of 1024 }; -QDebug operator<<(QDebug debug, const Assignment &assignment); - #endif /* defined(__hifi__Assignment__) */