示例#1
0
static void
ldo_putref(ScarabSession * session, int reference, ScarabDatum * obj)
{
	LDO_Session    *s;
	ScarabDatum    *ref;

	s = (LDO_Session *) session->encoder;
	ref = scarab_new_integer(reference);

	scarab_dict_put(s->refs, ref, obj);
	scarab_free_datum(ref);
	scarab_free_datum(obj);
}
示例#2
0
static ScarabDatum *
ldo_getref(ScarabSession * session, int reference)
{
	LDO_Session    *s;
	ScarabDatum    *ref;
	ScarabDatum    *obj;

	s = (LDO_Session *) session->encoder;
	ref = scarab_new_integer(reference);
	obj = scarab_dict_get(s->refs, ref);

	scarab_free_datum(ref);

	return obj;
}
示例#3
0
Datum VariableRegistry::generateCodecDatum() {
	
	ScarabDatum *codec = NULL;
    shared_ptr<Variable> var;
	
	
	boost::mutex::scoped_lock s_lock(lock);

    int dictSize = master_variable_list.size();
	
	codec = scarab_dict_new(dictSize, &scarab_dict_times2);
	
	
    for(int i = 0; i < dictSize; i++) {
        var = master_variable_list[i];
		
		if(var == NULL) { 
            continue; 
        }
        
		int codec_code = var->getCodecCode();
		
		if(codec_code == RESERVED_CODEC_CODE) {
			continue;
		}
        
		VariableProperties *props = var->getProperties();
		
        if(props == NULL){ 
            continue; 
        }
        
        Datum serialized_var(props->operator Datum());
		
        if(serialized_var.isUndefined()) {
            mdebug("local parameter null value at param (%d)", i);
        }
		ScarabDatum *codec_key = scarab_new_integer(codec_code);
        scarab_dict_put(codec, codec_key, serialized_var.getScarabDatum());
		scarab_free_datum(codec_key);
    }
	
	
    Datum returnCodec(codec);
	scarab_free_datum(codec);
    return returnCodec;  
}
示例#4
0
static ScarabDatum *
ldo_read(ScarabSession * session)
{
	LDO_Session    *s;
	ScarabDatum    *attrib;
	ScarabDatum    *value;
	long long             refid;
	long long             sign;
	long long             esign;
	long long             len;
	unsigned char   lastByte;

	s = (LDO_Session *) session->encoder;
	attrib = NULL;
	refid = -1;
	sign = 1;
	esign = 1;

    // PAJ really wish the guys who wrote this left some comments in here
    // this read calls the stream head read which calls stream_read in
    // stream_tcpip.c.  This is the place where all the socket comm stuff 
    // happens.  This is where recv is called....and will block
	if (scarab_session_read(session, &lastByte, 1) != 1)
		return NULL;

	if (DEFINE_REFERENCE == lastByte)
	{
		refid = ldo_readber(session);
		if (scarab_session_read(session, &lastByte, 1) != 1)
			return NULL;
	}

	if (ATTRIBUTES == lastByte)
	{
		if (scarab_session_read(session, &lastByte, 1) != 1)
			return NULL;

		if (REFERENCE == lastByte)
		{
			refid = ldo_readber(session);
		} else if (DEFINE_REFERENCE == lastByte)
		{
			refid = ldo_readber(session);
			ldo_putref(session, refid, ldo_read_dict(session));
		}
		attrib = ldo_getref(session, refid);
		if (scarab_session_read(session, &lastByte, 1) != 1)
			return NULL;
	}

	switch (lastByte)
	{
		/*
		 * integer
		 */
	case INTEGER_N:
		sign = -1;
	case INTEGER_P:
		value = scarab_new_integer(ldo_readber(session) * sign);
		break;

		/*
		 * float
		 */
	case FLOAT_NN:
		esign = -1;
	case FLOAT_NP:
		sign = -1;
		value = scarab_new_float(ldo_readfloat(session, sign, esign));
		break;
	case FLOAT_PN:
		esign = -1;
	case FLOAT_PP:
		value = scarab_new_float(ldo_readfloat(session, sign, esign));
		break;
	case FLOAT_INF:
		value = scarab_new_atomic();
		value->type = SCARAB_FLOAT_INF;
		break;
	case FLOAT_OPAQUE:
		//value = scarab_new_atomic();
		//value->type = SCARAB_FLOAT_NAN;
//        fprintf(stderr, "This is f***ing ridiculous!!!!!\n");
//        fprintf(stderr, "Reading a god damn float nan\n");
		len = ldo_readber(session);
		value = scarab_new_atomic();
		value->type = SCARAB_FLOAT_OPAQUE; //HAXXOR WARNING
		value->data.opaque.size = len;
		value->data.opaque.data = (unsigned char*)scarab_mem_malloc(
													sizeof(char) * len);
        
		scarab_session_read(session, value->data.opaque.data, len);
		break;

		/*
		 * opaque thingies
		 */
	case OPAQUE:
		len = ldo_readber(session);
		value = scarab_new_atomic();
		value->type = SCARAB_OPAQUE;
		value->data.opaque.size = len;
		value->data.opaque.data = (unsigned char*)scarab_mem_malloc(
													sizeof(char) * len);

		scarab_session_read(session, value->data.opaque.data, len);
		break;

		/*
		 * compound
		 */
	case DICTIONARY:
		value = ldo_read_dict(session);
		break;
	case LIST:
		value = ldo_read_list(session);
		break;
	case REFERENCE:
		value = ldo_getref(session, ldo_readber(session));
		break;
	case 0x0:  // DDC August 10, 2005, changed from NULL
		value = scarab_new_atomic();
		value->type = SCARAB_NULL;
		break;
	default:
		return NULL;
	}

	/*
	 * save the reference if there is one
	 */
	if (refid != -1)
		ldo_putref(session, refid, value);

	/*
	 * if attributes were used, add them to the value
	 */
	if (attrib != NULL)
		value->attributes = attrib;

	return value;
}
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;
//    }
}
示例#6
0
void VariableRegistry::updateFromCodecDatum(const Datum &codec) {
	mprintf(M_SYSTEM_MESSAGE_DOMAIN,
			"Received new codec, updating variable registry.");
	
    if(!codec.isDictionary()) {
        merror(M_SYSTEM_MESSAGE_DOMAIN,
			   "Invalid codec received.  Registry is unchanged.");
		return;
	}
 	
	boost::mutex::scoped_lock s_lock(lock);
	
	master_variable_list.clear();
	
	// add the placeholders
	//addPlaceholders();
	
	
	//////////////////////////////////////////////////////////////////
	// now add what's in the codec 
	
	ScarabDatum *datum = codec.getScarabDatum();
	
	ScarabDatum ** keys = datum->data.dict->keys;
	int size = datum->data.dict->tablesize;
	
	
	
	int maxCodecCode = -1;
	// find the maximum codec value
	for(int i = 0; i < size; ++i) {
		if(keys[i]) {
			long long code = keys[i]->data.integer;
			maxCodecCode = (maxCodecCode < code) ? code : maxCodecCode;
		}
	}
		
	// add each variable in order to the registry
	for(int i = N_RESERVED_CODEC_CODES; i<=maxCodecCode; ++i) {
		ScarabDatum *key = scarab_new_integer(i);
		ScarabDatum *serializedVariable = scarab_dict_get(datum, key);
		scarab_free_datum(key);
		
		if(!serializedVariable) {
            shared_ptr<EmptyVariable> empty_var(new EmptyVariable);
            master_variable_list.push_back(empty_var);
            continue;
        } else {
			if(serializedVariable->type != SCARAB_DICT) {
				// these must be  placeholder datums in the package
				// that we should ignore.
				mwarning(M_SYSTEM_MESSAGE_DOMAIN,
						 "Bad variable received from network stream");
				
                shared_ptr<EmptyVariable> empty_var(new EmptyVariable);
                master_variable_list.push_back(empty_var);
                continue;
			}
						
			VariableProperties *props = 
				new VariableProperties(serializedVariable);
			
			if(props == NULL){
				mwarning(M_SYSTEM_MESSAGE_DOMAIN,
						 "Bad variable received from network stream");
				
                shared_ptr<EmptyVariable> empty_var(new EmptyVariable);
                master_variable_list.push_back(empty_var);
                continue;
			}
			
			shared_ptr<Variable> newvar(new GlobalVariable(props));
			newvar->setCodecCode(i); //necessary? .. Yup
			
			master_variable_list.push_back(newvar);
            
            std::string tag = newvar->getVariableName();
            if(!tag.empty()){
                master_variable_dictionary[tag] = newvar;
            }
		}
	}
}