inital setup for static assignment mapped file

This commit is contained in:
Stephen Birarda 2013-09-24 14:41:26 -07:00
parent daa5493973
commit bed4819313
3 changed files with 143 additions and 92 deletions

View file

@ -27,6 +27,7 @@
#include <stdlib.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QMap>
#include <QtCore/QMutex>
@ -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) {

View file

@ -9,37 +9,79 @@
#include "PacketHeaders.h"
#include "SharedUtil.h"
#include <QtCore/QDataStream>
#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();
}
}
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;
}

View file

@ -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__) */