From bb073bdff3f4a2519ed2ae0c83cfe9549dd47b9b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 9 Sep 2013 11:59:58 -0700 Subject: [PATCH] fork off n children and keep the parent process as a monitor --- assignment-client/src/main.cpp | 126 ++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 67d2a1e021..72ae826ef2 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -32,16 +32,19 @@ int main(int argc, const char* argv[]) { } const char* NUM_FORKS_PARAMETER = "-n"; - const char* numForksIncludingParentString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER); + const char* numForksString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER); - if (numForksIncludingParentString) { - int numForksIncludingParent = atoi(numForksIncludingParentString); - qDebug() << "Starting" << numForksIncludingParent << "assignment clients."; + int processID = 0; + int numForks = 0; + + if (numForksString) { + numForks = atoi(numForksString); + qDebug() << "Starting" << numForks << "assignment clients."; + - int processID = 0; // fire off as many children as we need (this is one less than the parent since the parent will run as well) - for (int i = 0; i < numForksIncludingParent - 1; i++) { + for (int i = 0; i < numForks; i++) { processID = fork(); if (processID == 0) { @@ -51,63 +54,70 @@ int main(int argc, const char* argv[]) { } } - // create a NodeList as an unassigned client - NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED); - - // set the custom assignment socket if we have it - if (customAssignmentSocket.sin_addr.s_addr != 0) { - nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket); - } - - // change the timeout on the nodelist socket to be as often as we want to re-request - nodeList->getNodeSocket()->setBlockingReceiveTimeoutInUsecs(ASSIGNMENT_REQUEST_INTERVAL_USECS); - - timeval lastRequest = {}; - - unsigned char packetData[MAX_PACKET_SIZE]; - ssize_t receivedBytes = 0; - - // grab the assignment pool from argv, if it was passed - const char* ASSIGNMENT_POOL_PARAMETER = "-p"; - const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_PARAMETER); - - // create a request assignment, accept all assignments, pass the desired pool (if it exists) - Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); - - while (true) { - if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) { - gettimeofday(&lastRequest, NULL); - // if we're here we have no assignment, so send a request - nodeList->sendAssignment(requestAssignment); + if (processID == 0 || numForks == 0) { + // this is one of the child forks or there is a single assignment client, continue assignment-client execution + + // create a NodeList as an unassigned client + NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED); + + // set the custom assignment socket if we have it + if (customAssignmentSocket.sin_addr.s_addr != 0) { + nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket); } - if (nodeList->getNodeSocket()->receive(packetData, &receivedBytes) && - packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) { + // change the timeout on the nodelist socket to be as often as we want to re-request + nodeList->getNodeSocket()->setBlockingReceiveTimeoutInUsecs(ASSIGNMENT_REQUEST_INTERVAL_USECS); + + timeval lastRequest = {}; + + unsigned char packetData[MAX_PACKET_SIZE]; + ssize_t receivedBytes = 0; + + // grab the assignment pool from argv, if it was passed + const char* ASSIGNMENT_POOL_PARAMETER = "-p"; + const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_PARAMETER); + + // create a request assignment, accept all assignments, pass the desired pool (if it exists) + Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); + + while (true) { + if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) { + gettimeofday(&lastRequest, NULL); + // if we're here we have no assignment, so send a request + nodeList->sendAssignment(requestAssignment); + } - // construct the deployed assignment from the packet data - Assignment deployedAssignment(packetData, receivedBytes); - - qDebug() << "Received an assignment - " << deployedAssignment << "\n"; - - // switch our nodelist DOMAIN_IP to the ip receieved in the assignment - if (deployedAssignment.getDomainSocket()->sa_family == AF_INET) { - in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getDomainSocket())->sin_addr; - nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); + if (nodeList->getNodeSocket()->receive(packetData, &receivedBytes) && + packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) { - qDebug() << "Changed domain IP to " << inet_ntoa(domainSocketAddr); + // construct the deployed assignment from the packet data + Assignment deployedAssignment(packetData, receivedBytes); + + qDebug() << "Received an assignment - " << deployedAssignment << "\n"; + + // switch our nodelist DOMAIN_IP to the ip receieved in the assignment + if (deployedAssignment.getDomainSocket()->sa_family == AF_INET) { + in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getDomainSocket())->sin_addr; + nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); + + qDebug() << "Changed domain IP to " << inet_ntoa(domainSocketAddr); + } + + if (deployedAssignment.getType() == Assignment::AudioMixer) { + AudioMixer::run(); + } else { + AvatarMixer::run(); + } + + qDebug() << "Assignment finished or never started - waiting for new assignment"; + + // reset our NodeList by switching back to unassigned and clearing the list + nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); + nodeList->clear(); } - - if (deployedAssignment.getType() == Assignment::AudioMixer) { - AudioMixer::run(); - } else { - AvatarMixer::run(); - } - - qDebug() << "Assignment finished or never started - waiting for new assignment"; - - // reset our NodeList by switching back to unassigned and clearing the list - nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); - nodeList->clear(); } + } else { + // don't bail until all children have finished + wait(NULL); } } \ No newline at end of file