static void job_check_func (gpointer data, gpointer user_data) { Job *job = (Job *)data; Gstreamill *gstreamill = (Gstreamill *)user_data; if (gstreamill->stop) { GST_ERROR ("waitting %s stopped", job->name); return; } /* stat report. */ if (gstreamill->daemon && (job->worker_pid != 0)) { job_stat_update (job); GST_INFO ("Job %s's average cpu: %d%%, cpu: %d%%, rss: %lu", job->name, job->cpu_average, job->cpu_current, job->memory); } if (*(job->output->state) != JOB_STATE_PLAYING) { return; } source_check (gstreamill, job); encoders_check (gstreamill, job); if (job->is_live) { sync_check (gstreamill, job); } /* check non live job eos */ if (!job->is_live) { gint i; gboolean eos = TRUE; for (i = 0; i < job->output->encoder_count; i++) { if (!(*(job->output->encoders[i].eos))) { eos = FALSE; break; } else { /* add #EXT-X-ENDLIST to playlist if output is m3u8 */ gchar *location, *property, *playlist1, *playlist2; property = g_strdup_printf ("encoder.%d.elements.hlssink.property.playlist-location", i); location = jobdesc_element_property_value (job->description, property); g_free (property); if (location != NULL) { g_file_get_contents (location, &playlist1, NULL, NULL); playlist2 = g_strdup_printf ("%s#EXT-X-ENDLIST\n", playlist1); g_file_set_contents (location, playlist2, strlen(playlist2), NULL); g_free (playlist1); g_free (playlist2); g_free (location); } } } if (eos) { stop_job (job, SIGTERM); job->eos = TRUE; } } }
static Ret main_loop_select_run(MainLoop* thiz) { DECLES_PRIV(priv, thiz); int i = 0; int n = 0; int fd = -1; int mfd = -1; int wait_time = 3600 * 3000; // int wait_time = 1000; int source_wait_time = 0; int ret = 0; struct timeval tv = {0}; Source* source = NULL; int count = 0; priv->running = 1; while(priv->running) { FD_ZERO(&(priv->fdset)); FD_ZERO(&(priv->err_fdset)); count = sources_manager_get_count(priv->sources_manager); logger_debug(priv->logger, "%s: sources count = %d", __func__, count); for (i = 0; i < count; i++) { source = NULL; sources_manager_get(priv->sources_manager, i, &source); if ((fd = source_get_fd(source)) >= 0) { FD_SET(fd, &(priv->fdset)); FD_SET(fd, &(priv->err_fdset)); if (fd > mfd) mfd = fd; ++n; } source_wait_time = source_check(source); logger_debug(priv->logger, "%s: source_wait_time = %d", __func__, source_wait_time); if (source_wait_time >= 0 && source_wait_time < wait_time) { wait_time = source_wait_time; } // process signal sources here; // TODO add time interval into source_signal if (source_get_type(source) == SOURCE_SIGNAL && source->active == 1) { source_dispatch(source); source->active = 0; } } logger_debug(priv->logger, "%s: wait_time = %d", __func__, wait_time); tv.tv_sec = wait_time / 1000; tv.tv_usec = (wait_time % 1000)*1000; ret = select(mfd + 1, &(priv->fdset), NULL, &(priv->err_fdset), &tv); for (i = 0; i < sources_manager_get_count(priv->sources_manager); ) { if (sources_manager_need_refresh(priv->sources_manager)) { break; } sources_manager_get(priv->sources_manager, i, &source); if (source->disable > 0) { sources_manager_del_source(priv->sources_manager, source); continue; } if ((fd = source_get_fd(source)) >= 0 && ret != 0) { if (ret > 0 && FD_ISSET(fd, &(priv->fdset))) { if (source_dispatch(source) != RET_OK) { sources_manager_del_source(priv->sources_manager, source); } else { ++i; } continue; } } else if (FD_ISSET(fd, &(priv->fdset))) { sources_manager_del_source(priv->sources_manager, source); continue; } if ((source_wait_time = source_check(source)) == 0) { if (source_dispatch(source) != RET_OK) { sources_manager_del_source(priv->sources_manager, source); } else { ++i; } continue; } ++i; } } return RET_OK; }