// Recevied a reply to a trigger ("sim.reply") static void reply_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str = NULL; json_t *request = NULL; ctx_t *ctx = arg; sim_state_t *curr_sim_state = ctx->sim_state; sim_state_t *reply_sim_state; if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL || !(request = Jfromstr (json_str))) { flux_log (h, LOG_ERR, "%s: bad reply message", __FUNCTION__); Jput (request); return; } // De-serialize and get new info reply_sim_state = json_to_sim_state (request); copy_new_state_data (ctx, curr_sim_state, reply_sim_state); if (handle_next_event (ctx) < 0) { flux_log (h, LOG_DEBUG, "No events remaining"); if (ctx->exit_on_complete) { log_msg_exit ("exit_on_complete is set. Exiting now."); } else { send_complete_event (h); } } free_simstate (reply_sim_state); Jput (request); }
static gboolean parse_MTrk (GstMidiParse * midiparse, guint8 * data, guint size) { GstMidiTrack *track; GstClockTime duration; /* ignore excess tracks */ if (midiparse->track_count >= midiparse->ntracks) return TRUE; track = g_slice_new (GstMidiTrack); track->data = data; track->size = size; reset_track (track, midiparse); midiparse->tracks = g_list_append (midiparse->tracks, track); midiparse->track_count++; /* now loop over all events and calculate the duration */ while (!track->eot) { handle_next_event (midiparse, track, NULL, NULL); } duration = gst_util_uint64_scale (track->pulse, 1000 * midiparse->tempo, midiparse->division); GST_DEBUG_OBJECT (midiparse, "duration %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); if (duration > midiparse->segment.duration) midiparse->segment.duration = duration; reset_track (track, midiparse); return TRUE; }
static GstFlowReturn gst_midi_parse_do_play (GstMidiParse * midiparse) { GstFlowReturn res; GList *walk; guint64 pulse, next_pulse = G_MAXUINT64; GstClockTime position, next_position; guint64 tick; pulse = midiparse->pulse; position = midiparse->segment.position; if (midiparse->segment_pending) { gst_pad_push_event (midiparse->srcpad, gst_event_new_segment (&midiparse->segment)); midiparse->segment_pending = FALSE; } GST_DEBUG_OBJECT (midiparse, "pulse %" G_GUINT64_FORMAT ", position %" GST_TIME_FORMAT, pulse, GST_TIME_ARGS (position)); for (walk = midiparse->tracks; walk; walk = g_list_next (walk)) { GstMidiTrack *track = walk->data; while (!track->eot && track->pulse == pulse) { res = handle_next_event (midiparse, track, play_push_func, NULL); if (res != GST_FLOW_OK) goto error; } if (!track->eot && track->pulse < next_pulse) next_pulse = track->pulse; } if (next_pulse == G_MAXUINT64) goto eos; tick = position / (10 * GST_MSECOND); GST_DEBUG_OBJECT (midiparse, "current tick %" G_GUINT64_FORMAT, tick); next_position = gst_util_uint64_scale (next_pulse, 1000 * midiparse->tempo, midiparse->division); GST_DEBUG_OBJECT (midiparse, "next position %" GST_TIME_FORMAT, GST_TIME_ARGS (next_position)); /* send 10ms ticks to advance the downstream element */ while (TRUE) { /* get position of next tick */ position = ++tick * (10 * GST_MSECOND); GST_DEBUG_OBJECT (midiparse, "tick %" G_GUINT64_FORMAT ", position %" GST_TIME_FORMAT, tick, GST_TIME_ARGS (position)); if (position >= next_position) break; midiparse->segment.position = position; res = play_push_func (midiparse, NULL, 0xf9, NULL, 0, NULL); if (res != GST_FLOW_OK) goto error; } midiparse->pulse = next_pulse; midiparse->segment.position = next_position; return GST_FLOW_OK; /* ERRORS */ eos: { GST_DEBUG_OBJECT (midiparse, "we are EOS"); return GST_FLOW_EOS; } error: { GST_DEBUG_OBJECT (midiparse, "have flow result %s", gst_flow_get_name (res)); return res; } }
// Recevied a request to join the simulation ("sim.join") static void join_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { int mod_rank; json_t *request = NULL; const char *mod_name = NULL, *json_str = NULL; double *next_event = (double *)malloc (sizeof (double)); ctx_t *ctx = arg; sim_state_t *sim_state = ctx->sim_state; uint32_t size; if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL || !(request = Jfromstr (json_str)) || !Jget_str (request, "mod_name", &mod_name) || !Jget_int (request, "rank", &mod_rank) || !Jget_double (request, "next_event", next_event)) { flux_log (h, LOG_ERR, "%s: bad join message", __FUNCTION__); goto out; } if (flux_get_size (h, &size) < 0) goto out; if (mod_rank < 0 || mod_rank >= size) { flux_log (h, LOG_ERR, "%s: bad rank in join message", __FUNCTION__); goto out; } flux_log (h, LOG_DEBUG, "join rcvd from module %s on rank %d, next event at %f", mod_name, mod_rank, *next_event); zhash_t *timers = sim_state->timers; if (zhash_insert (timers, mod_name, next_event) < 0) { // key already // exists flux_log (h, LOG_ERR, "duplicate join request from %s, module already exists in " "sim_state", mod_name); goto out; } // clear next event so it is not freed below next_event = NULL; // TODO: this is horribly hackish, improve the handshake to avoid // this hardcoded # of modules. maybe use a timeout? ZMQ provides // support for polling etc with timeouts, should try that static int num_modules = 3; num_modules--; if (num_modules <= 0) { if (handle_next_event (ctx) < 0) { flux_log (h, LOG_ERR, "failure while handling next event"); return; } } out: Jput (request); free (next_event); }