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); }
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; }
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; }
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; // } }
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; } } } }