void logDescriptiveScarabMessage(ScarabSession * s) { int scCode = getScarabError(s); // scarab error code int oserr = getScarabOSError(s); const char *scarab_error_string = scarab_strerror(scCode); mnetwork("ERROR: SCR-%5.5i: %s: %s", scCode, scarab_moderror(scCode), scarab_error_string); if(oserr) { const char *scarab_os_error_string = scarab_os_strerror(oserr); mnetwork("OSERR: %i: %s", oserr, scarab_os_error_string); } }
NetworkReturn * ScarabServer::startListening() { NetworkReturn * rc = new NetworkReturn(); mdebug("startListening()"); if(listening) { rc->setMWorksCode(NR_SUCCESS_NETWORK_MESSAGE); rc->setInformation("Server is already running."); return rc; } if(listenUri.size() == 0) { rc->setMWorksCode(NR_FAILED); rc->setInformation("URI not specified for server"); return rc; } std::string fullUri = createScarabURI(); if(fullUri.size() == 0) { rc->setMWorksCode(NR_FAILED); rc->setInformation("Could not create a valid URI"); return rc; } int error = 1; // mnetwork("Trying listening socket at %s on port %d", // listenAddress.c_str(), // listenPort); // mprintf("URI = %s", fullUri.c_str()); listeningSocket = scarab_session_listen(fullUri.c_str()); error = getScarabError(listeningSocket); while(error) { mnetwork("Failed to open a listening socket at %s on port %d", listenAddress.c_str(), listenPort); //mdebug("Maybe print out why here??"); // if there is another available port we will try again if(!chooseNewPort()) { rc->setMWorksCode(NR_FATAL_ERROR); rc->setPackageCode(error); rc->setOSErrorCode(getScarabOSError(listeningSocket)); rc->setInformation("Ran out of ports to listen on. Networking impossible"); rc->appendInformation(getScarabErrorDescription(error)); rc->appendInformation(getOSErrorDescription( getScarabOSError(listeningSocket))); return rc; } fullUri = createScarabURI(); listeningSocket = scarab_session_listen(fullUri.c_str()); error = getScarabError(listeningSocket); } mnetwork("Listening socket started at %s on port %d", listenAddress.c_str(), listenPort); listening = true; return rc; }
int ScarabServer::service() { if(1){ //while(1) { if(getScarabError(listeningSocket)) { merror(M_NETWORK_MESSAGE_DOMAIN, "Session failure on listening socket"); logDescriptiveScarabMessage(listeningSocket); return -1; } // this number should eventually come from the network // manager at construction time. connectionLock->lock(); int check = numberOfConnectedClients; connectionLock->unlock(); if(check == maxConnections) { mwarning(M_NETWORK_MESSAGE_DOMAIN, "Maximum number of clients connected"); return -1; } // the clients here are accept clients who wait for // connection clients to connect to them. tempClient = new ScarabServerConnection(incoming_event_buffer, outgoing_event_buffer, clientThreadInterval); shared_ptr<NetworkReturn> acceptRet; acceptRet = tempClient->accept(listeningSocket); mprintf("Accepting remote client"); if(!acceptRet->wasSuccessful()) { // the accept failed but it may have just timed out delete tempClient; tempClient = NULL; if(scarab_did_select_timeout(acceptRet->getPackageCode())) { // return from the service function and reschedule it boolLock->lock(); if(accepting) { boolLock->unlock(); return 1; //continue; } else { boolLock->unlock(); return 1; } } else { merror(M_NETWORK_MESSAGE_DOMAIN, "Server failed to accept client"); return -1; } } // the connection was established. mnetwork("Connection accepted from ..."); tempClient->start(); M_HASLOCK(connectionLock); clients[numberOfConnectedClients] = tempClient; numberOfConnectedClients++; M_HASUNLOCK(connectionLock); outgoing_event_buffer->putEvent(SystemEventFactory::serverConnectedClientResponse()); } // Some omissions by Paul: // Need to reschedule the accept thread (otherwise, this will be the last // client we accept). Also, we need to startListening again (which seems // like it probably ought to have been rolled into accepting, but that // is a another mess to clean up on another day... startListening(); scheduleAccept(); // we also should send a fresh codec so that this new client knows what is // up if it is joining the party late //buffer_manager->putEvent(SystemEventFactory::codecPackageEvent()); outgoing_event_buffer->putEvent(SystemEventFactory::componentCodecPackage()); outgoing_event_buffer->putEvent(SystemEventFactory::codecPackage()); // TODO: move this out into some sort of "announceSystemState" call? if(GlobalDataFileManager != NULL && GlobalDataFileManager->isFileOpen()){ std::string fname = GlobalDataFileManager->getFilename(); outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(fname, M_COMMAND_SUCCESS)); } outgoing_event_buffer->putEvent(SystemEventFactory::currentExperimentState()); outgoing_event_buffer->putEvent(SystemEventFactory::protocolPackage()); global_variable_registry->announceAll(); return 0; }