int remove_rule(zctx_t * context, zhash_t * hash, char * rule_id) { void * pipe = zhash_lookup(hash, rule_id); if(!pipe) return 0; zstr_send(pipe, "Destroy"); recv_sync("ok", pipe); zhash_delete(hash, rule_id); zsocket_destroy(context, pipe); zclock_log("rule %s destroyed", rule_id); return 1; }
void add_monitor(rulepackage_t * rpkg, zmsg_t * reply) { // unconditionally fork a monitor for each line // they'll die when they get a channel change int i; for(i=1; i<4; i++) { monitorconfig_t * mconf = malloc(sizeof(monitorconfig_t)); mconf->line_id = i; mconf->source_worker = rpkg->servicename; mconf->out_socket = rpkg->base_config->portwatcher_endpoint; mconf->channel = rpkg->channel; void * monitor_pipe = zthread_fork(rpkg->context, watch_port, (void*)mconf); send_sync("ping", monitor_pipe); recv_sync("pong", monitor_pipe); zsocket_destroy(rpkg->context, monitor_pipe); } zmsg_pushstr(reply, "ok"); }
void generic_worker(void * cvoid, zctx_t * context, void * pipe) { workerconfig_t *config = (workerconfig_t*) cvoid; zhash_t * rules = zhash_new(); child_handshake(pipe); zmsg_t *reply = NULL; void * rule_pipe = NULL; char * ninja = config->base_config->identity; char * channel = config->channel; char * servicename = malloc(strlen(ninja) + strlen(channel) + 2); sprintf(servicename, "%s:%s", ninja,channel); // sqlite stuff int rc; char * tail = NULL; sqlite3 *db = init_db(servicename); sqlite3_stmt * insert_stmt; zclock_log("%s worker preparing rules...", servicename); sqlite3_prepare_v2(db, "insert into rules VALUES (@RULEID, @TRIGGER_NAME, @TARGET_WORKER, @AUTH, @ADDINS);", 512, &insert_stmt, NULL); zclock_log("%s worker reloading rules...", servicename); reload_rules(context, db, servicename, channel, rules); zclock_log("%s worker connecting...", servicename); mdwrk_t *session = mdwrk_new (config->base_config->broker_endpoint, servicename, 0); zclock_log("%s worker connected!", servicename); while (1) { zclock_log("%s worker waiting for work.", servicename); zmsg_t *request = mdwrk_recv (session, &reply); if (request == NULL) break; // Worker was interrupted char * command = zmsg_popstr(request); char * rule_id = zmsg_popstr(request); zclock_log("%s worker servicing request %s for rule %s", servicename,command,rule_id); reply = zmsg_new(); if (strcmp(command, "AddTrigger") == 0) { zclock_log("new trigger!"); if (zhash_lookup(rules, rule_id)) { // already have a rule with that id! WTF?? // FIXME should probably delete this and reinstate zclock_log("Received duplicate rule %s, ignoring", rule_id); zmsg_destroy(&request); zmsg_pushstr(reply, "duplicate"); } else { triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t)); create_triggerconfig(tconf, request, channel, rule_id); char * created = create_trigger(rules, rule_id, context, tconf); if(NULL == created) { // happy path, so add to db sqlite3_bind_text(insert_stmt, 1, tconf->rule_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 2, tconf->trigger_name, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 3, tconf->target_worker, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 4, tconf->auth, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 5, tconf->addins, -1, SQLITE_TRANSIENT); sqlite3_step(insert_stmt); sqlite3_clear_bindings(insert_stmt); sqlite3_reset(insert_stmt); zmsg_pushstr(reply, "ok"); } else { zclock_log("create_trigger failed: %s", created); zmsg_pushstr(reply, created); } free(created); } } else if (strcmp(command,"RemoveRule") == 0) { if (rule_pipe=zhash_lookup(rules, rule_id)) { // found it zclock_log("rule %s exists, removing.", rule_id); send_sync("Destroy",rule_pipe); zclock_log("rule %s waiting for OK from pipe", rule_id); recv_sync("ok", rule_pipe); zsocket_destroy(context, rule_pipe); zhash_delete(rules, rule_id); zmsg_pushstr(reply, "ok"); zclock_log("rule %s completely destroyed", rule_id); } else { // not there! zclock_log("Received delete trigger request for nonexistent rule %s, ignoring", rule_id); zmsg_pushstr(reply, "rule not found"); } } else if (strcmp(command, "AddMonitor")==0) { // unconditionally fork a monitor for each line // they'll die when they get a channel change int i; for(i=1; i<4; i++) { monitorconfig_t * mconf = malloc(sizeof(monitorconfig_t)); mconf->line_id = i; mconf->source_worker = servicename; mconf->out_socket = config->base_config->portwatcher_endpoint; mconf->channel = channel; void * monitor_pipe = zthread_fork(context, watch_port, (void*)mconf); send_sync("ping", monitor_pipe); recv_sync("pong", monitor_pipe); zsocket_destroy(context, monitor_pipe); } zmsg_pushstr(reply, "ok"); } else { zclock_log("Can't handle command %s: ignoring", command); } zmsg_destroy(&request); } mdwrk_destroy (&session); return; }
static int set_new_event( int t ) { int ptr; unsigned char *data; int count; int follower; __GETMDX; data = mdx->data; ptr = mdx->track[t].current_mml_ptr; count = 0; follower = 0; #if 0 if ( ptr+1 <= mdx->length && t>7 ) { fprintf(stderr,"%2d %2x %2x\n",t,data[ptr],data[ptr+1]); fflush(stderr); } #endif if ( data[ptr] <= MDX_MAX_REST ) { /* rest */ note_off(t); count = data[ptr]+1; mdx->track[t].gate = count+1; follower=0; } else if ( data[ptr] <= MDX_MAX_NOTE ) { /* note */ note_on( t, data[ptr]); count = data[ptr+1]+1; do_quantize( t, count ); follower = 1; } else { switch ( data[ptr] ) { case MDX_SET_TEMPO: set_tempo( data[ptr+1] ); follower = 1; break; case MDX_SET_OPM_REG: set_opm_reg( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_SET_VOICE: set_voice( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PHASE: set_phase( t, data[ptr+1] ); follower = 1; break; case MDX_SET_VOLUME: set_volume( t, data[ptr+1] ); follower = 1; break; case MDX_VOLUME_DEC: dec_volume( t ); follower = 0; break; case MDX_VOLUME_INC: inc_volume( t ); follower = 0; break; case MDX_SET_QUANTIZE: set_quantize( t, data[ptr+1] ); follower = 1; break; case MDX_SET_KEYOFF: set_keyoff( t ); follower = 0; break; case MDX_REPEAT_START: mdx->track[t].loop_counter[mdx->track[t].loop_depth] = data[ptr+1]; if ( mdx->track[t].loop_depth < MDX_MAX_LOOP_DEPTH ) mdx->track[t].loop_depth++; follower = 2; break; case MDX_REPEAT_END: if (--mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 0 ) { if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0; } else { if ( data[ptr+1] >= 0x80 ) { ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2; } else { ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] - 2; } } follower = 2; break; case MDX_REPEAT_BREAK: if ( mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 1 ) { if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0; ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] -2 +2; } follower = 2; break; case MDX_SET_DETUNE: set_detune( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_SET_PORTAMENT: set_portament( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_DATA_END: if ( data[ptr+1] == 0x00 ) { count = -1; note_off(t); follower = 1; } else { ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2; mdx->track[t].infinite_loop_times++; follower = 2; } break; case MDX_KEY_ON_DELAY: follower = 1; break; case MDX_SEND_SYNC: send_sync( data[ptr+1] ); follower = 1; break; case MDX_RECV_SYNC: recv_sync( t ); follower = 0; count = 1; break; case MDX_SET_FREQ: set_freq( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PLFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_plfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_plfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_ALFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_alfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_alfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_OPMLFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_hlfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_hlfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_LFO_DELAY: set_lfo_delay( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PCM8_MODE: follower = 0; break; case MDX_FADE_OUT: if ( data[ptr+1]==0x00 ) { follower = 1; set_fade_out( 5 ); } else { follower = 2; set_fade_out( data[ptr+2] ); } break; default: count = -1; break; } } ptr += 1+follower; mdx->track[t].current_mml_ptr = ptr; return count; }
void trigger(void *cvoid, zctx_t * context, void * control) { triggerconfig_t * c = (triggerconfig_t*) cvoid; //set up msgpack stuff zclock_log("watch_port started!"); msgpack_zone mempool; msgpack_zone_init(&mempool, 2048); // TODO char * user_id = "17"; // TODO get broker in somehow char * broker = "tcp://au.ninjablocks.com:5773"; mdcli_t * client = mdcli_new(broker, 1); //VERBOSE triggermemory_t trigger_memory; msgpack_object * addins_obj = parse_msgpack(&mempool, c->addins); if(!parse_addins(addins_obj, &trigger_memory)) { //bad message zclock_log("bad trigger definition"); msgpack_object_print(stdout, *addins_obj); send_sync("bad trigger", control); return; } zclock_log("Creating trigger: target %s, rule_id %s, name %s", c->target_worker, c->rule_id, c->trigger_name); dump_trigger(&trigger_memory); triggerfunction trigger_func; if(!(trigger_func = find_trigger(c->channel, c->trigger_name))) { zclock_log("no trigger found for channel %s, trigger %s", c->channel, c->trigger_name); send_sync("no such trigger", control); return; } void * line = zsocket_new(context, ZMQ_SUB); // what line are we on? // this comes in the addins. char * linesocket = to_linesocket(trigger_memory.line_id); zclock_log("trigger is connecting to listen on %s", linesocket); zsocket_connect(line, linesocket); zsockopt_set_unsubscribe(line, ""); zsockopt_set_subscribe(line, "VALUE"); recv_sync("ping", control); send_sync("pong", control); zmq_pollitem_t items [] = { { line, 0, ZMQ_POLLIN, 0 }, { control, 0, ZMQ_POLLIN, 0 } }; while(1) { // listen on control and line zmq_poll (items, 2, -1); if (items[1].revents & ZMQ_POLLIN) { zclock_log("rule %s received message on control pipe", c->rule_id); // control message // really only expecting DESTROY zmsg_t * msg = zmsg_recv(control); char * str = zmsg_popstr(msg); zmsg_destroy(&msg); if (strcmp("Destroy", str) == 0) { zclock_log("rule %s will quit on request", c->rule_id); free(str); send_sync("ok", control); zclock_log("rule %s quitting on request", c->rule_id); break; } else { zclock_log("unexpected command %s for rule %s", str, c->rule_id); free(str); send_sync("ok", control); } } if (items[0].revents & ZMQ_POLLIN) { // serial update zmsg_t * msg = zmsg_recv(line); zframe_t * cmd = zmsg_pop(msg); if(zframe_streq(cmd, "CHANNEL_CHANGE")) { // TODO // must have been dormant to have gotten this char * new_channel = zmsg_popstr(msg); if(strcmp(c->channel, new_channel) == 0) { // oh, happy day! We're relevant again. // reactivate and start looking at reset levels. zclock_log("line %d: changed channel from %s to %s: trigger coming back to life", trigger_memory.line_id, c->channel, new_channel); zsockopt_set_subscribe(line, "VALUE"); zsockopt_set_unsubscribe(line, "CHANNEL_CHANGE"); } free(new_channel); } else if (zframe_streq(cmd, "VALUE")) { zframe_t * vframe = zmsg_pop(msg); int value; memcpy(&value, zframe_data(vframe), sizeof(int)); char * update_channel = zmsg_popstr(msg); if(strcmp(c->channel, update_channel) != 0) { // channel changed, go dormant // this is legit according to my tests at // https://gist.github.com/2042350 zclock_log("line %d: changed channel from %s to %s: trigger going dormant", trigger_memory.line_id, c->channel, update_channel); zsockopt_set_subscribe(line, "CHANNEL_CHANGE"); zsockopt_set_unsubscribe(line, "VALUE"); } else if(trigger_func(&trigger_memory, value)) { send_trigger(client, c->target_worker, c->rule_id, value, user_id); } free(update_channel); } else { // shouldn't ever happen. zclock_log("shouldn't have received command %s\n", zframe_strdup(cmd)); } zmsg_destroy(&msg); zframe_destroy(&cmd); } } msgpack_zone_destroy(&mempool); }
int main(int argc, char **argv) { unsigned long i = 1; char Err[BUFSIZ]; #ifdef PVM unsigned int j = 0L; #endif /* There is no signal handling under parix. */ if(((int)signal(SIGINT, (void (*)(int)) myInterrupt) == -1) || ((int)signal(SIGFPE, (void (*)(int)) Arithmetic) == -1)) panic(A_FATAL, "child-main", "signal call went wrong :%s : %d", __FILE__, __LINE__); strcpy(hlp, argv[0]); program_name = hlp; initDef(&eps); /* initialize structure */ ipOptPrc(&eps, argc, argv); /* process options. */ #ifdef PVM eps.tid = pvm_mytid(); /* tid of process. */ strcpy(eps.Group, eps.Suffix); /* Create Group name. */ if((eps.inst = pvm_joingroup(eps.Group)) < 0) panic(A_FATAL, "child-main", "pvm grouping for group %s failed : %s : %d\n", eps.Group, __FILE__, __LINE__); printf("Slave with tid %d and inst %d started\n", eps.tid, eps.inst); /* To get more diversity, each Population gets other external parameters.*/ if(eps.SigDim > 0) eps.SigStart += (0.1 * (double) eps.inst); /* if(eps.SigDim > 0) { if(eps.SigDim == 1) eps.TauOne *= (0.1 * (double) eps.inst); else eps.TauLcl *= (0.1 * (double) eps.inst); } if(eps.PDim > 0) { if(eps.PDim == 1) { eps.GamOne *= (double) eps.inst; eps.PStart *= (double) eps.inst; } else eps.GamLcl *= (double) eps.inst; } #ifdef DEBUG fprintf(stderr, "%d:Tau = %g, Gamma = %g\n", eps.inst, eps.TauLcl, eps.GamOne); #endif */ sprintf(&hlp[strlen(hlp)], ".%d", eps.tid); if(pvm_barrier(eps.Group, eps.Tasks+1) < 0) panic(A_WARN, "child-main", "pvm barrier error : %s : %d\n", __FILE__, __LINE__); printf("\n%s as instance %d activ.\n", program_name, eps.inst); #endif /* PVM */ if(ipOptChk(&eps, Err)) { /* check parameter consistency */ fprintf(stderr,"%s",Err); /* print warning message */ panic(A_FATAL, "ipOptPrc", "Parameter inconsistency :\n%s\n%s : %d", Err, __FILE__, __LINE__); } #ifndef PVM printf("\n%s activ.\n", program_name); #endif #ifdef PVM if(NULL == (MigrationBuffer = (individual_tPtr *) calloc(eps.Neighbours, sizeof(individual_tPtr)))) panic(E_FATAL, "main-child", "not enough memory : %s : %d", __FILE__, __LINE__); for(j = 0; j < eps.Neighbours; j++) MigrationBuffer[j]= inNewIndividual(eps.XDim, eps.DDim, eps.SigDim, eps.AlpDim, eps.PDim); #endif initSuffix(&eps); /* initialize suffix, here string from ES.in*/ parsFormatString(&eps); /* pars format string */ pop = poNewPopulation(&eps); for (i = 1; i <= eps.TotExp; i++) { /* experiment loop */ ExpNbr = i; initPop(&eps, pop, i); #ifdef PVM /* Initialization of MigrationBuffer. */ for(j = 0; j < eps.Neighbours; j++) { if(j < pop->mu) inCopyIndividual(poGetIndividual(j+1, pop), MigrationBuffer[j]); else inCopyIndividual(poGetIndividual(pop->mu, pop), MigrationBuffer[j]); } #endif dataParLog(&eps); /* dump parameters */ fioTimeOut(&eps); /* get start time */ PopulationEVAL(&eps, pop, "parents"); dataCol(&eps, pop, i); if (eps.GfxFlg) gnInitGnuPipe(&eps); #ifdef PVM send_Best(&eps, pop); #endif while (!termExp(&eps)) { /* ES main loop */ eps.GenCnt++; PopulationCREATE(&eps, pop); /* recombination and mutation including the concept of letal mutations. */ PopulationEVAL(&eps, pop, "offspring"); PopulationSELECT(&eps, pop); dataCol(&eps, pop, i); if(eps.GfxFlg && (eps.GenCnt % eps.GfxIvl == 0)) gnPlotGnuPipe(&eps); /* plot data */ #ifdef PVM send_Best(&eps, pop); if(eps.GenCnt % eps.IsolationTime == 0) { send_Neighbours(&eps, pop); if(eps.Communication == COMMUNICATION_SYNCHRON) recv_sync(&eps, MigrationBuffer); } if(eps.Communication == COMMUNICATION_ASYNCHRON) recv_async(&eps, MigrationBuffer); for(j = 0; j < eps.Neighbours && j < pop->mu; j++) inCopyIndividual(MigrationBuffer[j], poGetIndividual(j+1, pop)); #endif } /* end ES main loop */ dataBst(&eps, pop, i); /* dump best ind. */ fioTimeOut(&eps); /* get end time */ } /* end experiment loop */ if(eps.GfxFlg) gnQuitGnuPipe(&eps); /* stop plotting */ reportExperiments(&eps); pop = poDeletePopulation(pop); #ifdef PVM if(pvm_initsend(PvmDataRaw) < 0) panic(A_FATAL,"child-main", "initsend for group %d failed : %s : %d", eps.inst, __FILE__, __LINE__); if((ptid = pvm_parent()) == PvmNoParent) panic(A_FATAL,"child-main", "pvm_parent for group %d failed : %s : %d", eps.inst, __FILE__, __LINE__); if(pvm_pkint(&(eps.tid), 1, 1) < 0) panic(A_FATAL,"child-main", "packing of tid failed : %s : %d", __FILE__, __LINE__); if(pvm_send(ptid, MSGTAG_END) < 0) panic(A_WARN, "child-main", "sending end message to master failed : %s : %d", __FILE__, __LINE__); pvm_barrier(eps.Group, eps.Tasks+1); pvm_lvgroup(eps.Group); for(j = 0; j < eps.Neighbours; j++) inDeleteIndividual(MigrationBuffer[j]); free(MigrationBuffer); #endif utGlobalTermination(&eps); printf("\n%s 1.0 terminated.\n", program_name); #ifdef PVM pvm_exit(); #endif exit(0); }
void parent_handshake(void*pipe) { send_sync("ping", pipe); recv_sync("pong", pipe); }
void child_handshake(void*pipe) { recv_sync("ping", pipe); send_sync("pong", pipe); }