Exemple #1
0
static ScarabDatum *
ldo_read_list(ScarabSession * session)
{
	int             i;
	int             len;
	ScarabDatum    *list;
	ScarabDatum	   *list_element;

	len = ldo_readber(session);
	list = scarab_list_new(len);

	for (i = 0; i < len; i++)
	{
		list_element = ldo_read(session);
		scarab_list_put(list, i, list_element);
		scarab_free_datum(list_element);
	}
	return list;
}
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;
//    }
}