Пример #1
0
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;
}
Пример #2
0
	int getScarabOSError(ScarabSession * session) {
		if(getScarabError(session)) {
			return scarab_session_getoserr(session);
		} else {
			return 0;
		}
	}
Пример #3
0
	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);
		} 
	}
Пример #4
0
int ScarabWriteConnection::service() {
	boost::mutex::scoped_lock lock(connectLock);

	static int n_written = 0;
	
	shared_ptr <Clock> clock = Clock::instance();
	static MWTime start_time = clock->getCurrentTimeUS();
//    static int functionCount = 0;
//    mdebug("entering write service");
//    struct timespec time_to_sleep;
//    time_to_sleep.tv_sec = 0;
//    time_to_sleep.tv_nsec = 200000000; //200 ms
//    while(1) {
//        mdebug("start write while loop");
//        if(servicing) {
//            // we are already servicing this connection.
//            mdebug("Already Servicing Writing");
//            M_ISUNLOCK;
//            continue;
//            //1return 1;
//        }
        servicing = true;
    
    //    mdebug("Started servicing write function count = %d", functionCount);
//        functionCount++;
        if(getScarabError(pipe)) {
            mwarning(M_NETWORK_MESSAGE_DOMAIN, "Session Failure on ID %ld", cid);
            servicing = false;
            if(sibling) {
                sibling->setInterrupt(true);
            }
            term = true;
            
            return -1;
        }

        // if we have been requested to get interrupted
        // if we are interrupted while processing events there will be a
        // slight delay while out task is re-scheduled
        if(interrupt) {
            mwarning(M_NETWORK_MESSAGE_DOMAIN,
					"Write Service Routine Interrupted on id %ld", cid);
            if(sibling) {
                sibling->setInterrupt(true);
            }
            ScarabDatum * termEvent;
            // puts a control event of type termination into a scarab package
            // and sends the package
            termEvent = scarab_list_new(SCARAB_EVENT_N_TOPLEVEL_ELEMENTS);
			
			ScarabDatum *termCode = scarab_new_integer(RESERVED_TERMINATION_CODE);
            scarab_list_put(termEvent, SCARAB_EVENT_CODEC_CODE_INDEX, termCode);
			scarab_free_datum(termCode);
			
			shared_ptr <Clock> clock = Clock::instance();
			ScarabDatum *time = scarab_new_integer(clock->getCurrentTimeUS());
            scarab_list_put(termEvent, SCARAB_EVENT_TIME_INDEX, time);
			scarab_free_datum(time);

            if(scarab_write(pipe, termEvent) == 0) {
                // success
                mdebug("Wrote termination message from id %ld", cid);
                servicing = false;
                term = true; // mark the connection for termination
                scarab_free_datum(termEvent);
				return 0;
            } else {
                mwarning(M_NETWORK_MESSAGE_DOMAIN,
					"Failed to Write Termination Sequence on socket %ld", cid);
                // even though there was an error we are going to 
                // terminate
                term = true; // mark the connection for termination
                scarab_free_datum(termEvent);
				return -1;
            }
			
			scarab_free_datum(termEvent);
        }
    
        // while we have events to process but havent been requested for
        // interruption.
        
		while(buffer_reader->nextEventExists() && !interrupt) {
            
            //MWTime event_time = newevent->getTime();
            //mEventType type = newevent->getEventType();
            //mVariable *var = newevent->getParam();
            ScarabDatum * scarab_event;
        			
			#define USE_EXPLICIT_BUFFERING	1
			#define BUFFER_HIGH_WATER_MARK	1
			#define MAX_EVENTS_TO_BUFFER	10000
			
			if(USE_EXPLICIT_BUFFERING && buffer_reader->hasAtLeastNEvents(BUFFER_HIGH_WATER_MARK)) {
			
				scarab_force_buffering(pipe, 1);
				
				// fill up the macro event
				int numEventsBuffered = 0;
				bool buffering = true;
				do {
					
					shared_ptr<Event> newevent = buffer_reader->getNextEvent();
					if(newevent == NULL) {
						// don't send anything if an event was NULL.
						servicing = false;
						scarab_free_datum(scarab_event);
						return 1;
					}
					
					scarab_event = newevent->toScarabDatum();

					// stop buffering when you run out of events, or you hit the max events
					if(!(buffering = buffer_reader->nextEventExists() && numEventsBuffered<MAX_EVENTS_TO_BUFFER)) {
						scarab_force_buffering(pipe, 0);
					}
					
					if(scarab_write(pipe, scarab_event) == 0) {
						n_written++;
					} else {
						merror(M_SYSTEM_MESSAGE_DOMAIN, "scarab buffered write error");
						servicing = false;
						return -1;
					}
					
					scarab_free_datum(scarab_event);
					++numEventsBuffered;
				} while(buffering);
				
			
			} else {
				
				// Single event write
				shared_ptr<Event> newevent = buffer_reader->getNextEvent();
				if(newevent == NULL) {
					// don't send anything if an event was NULL.
					servicing = false;
					return 1;
				}
				
				scarab_event = newevent->toScarabDatum();
								
				if(scarab_write(pipe, scarab_event) == 0) {
					n_written++;
				} else {
					merror(M_SYSTEM_MESSAGE_DOMAIN, "scarab write error");
					servicing = false;
					return -1;
				}
				
				scarab_free_datum(scarab_event);
				
			}
			
			// Some reporting
			#define  N  1000
			static int last_nwritten = 0;
			if(n_written - last_nwritten >= N){
				last_nwritten = n_written;
				
				MWTime now = clock->getCurrentTimeUS();
				
				/*fprintf(stderr, "last: %lld, now: %lld\n",
							start_time,
							now
							); */
//				fprintf(stderr, "%g events / sec (%d event in %lld usec)\n",
//							(double)N / howlong,
//							N, now - start_time
//							);
//				fprintf(stderr, "Number of items unserviced: %d\n",
//						buffer_reader->getNItemsUnserviced());
//				fflush(stderr);
				start_time = now;
			}
        } 


        servicing = false;

        return 1;
//    }
}
Пример #5
0
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;
}