int service_init() { struct service *srv = service_ref(); struct softgred_config *cfg = softgred_config_ref(); // if empty, set default values! if (!cfg->srv_bind_in) cfg->srv_bind_in = strdup(SOFTGRED_DEFAULT_SERVICE_IFACE); if (cfg->srv_port == 0) cfg->srv_port = SOFTGRED_DEFAULT_SERVICE_PORT; if (cfg->srv_max_listen == 0) cfg->srv_max_listen = SOFTGRED_DEFAULT_SERVICE_MAX; D_DEBUG0("Listening \"SoftGREd Service\", listening in %s:%d with max %d accepts\n", cfg->srv_bind_in, cfg->srv_port, cfg->srv_max_listen ); if (pthread_create(&srv->tid, NULL, thread_service, NULL) < 0) { D_CRIT("Problems with pthread_create(), leaving.\n"); return -1; } return 0; }
int service_end() { struct service *srv = service_ref(); D_DEBUG0("Unitializing SoftGREd Service\n"); pthread_cancel(srv->tid); if (pthread_detach(srv->tid) < 0) { D_CRIT("Problems with pthread_detach(), leaving.\n"); return -1; } return 0; }
static void * serviceprobe_thread(void *aux) { service_t *t; th_subscription_t *s; int was_doing_work = 0; streaming_queue_t sq; streaming_message_t *sm; // transport_feed_status_t status; int run; const char *err; channel_t *ch; uint32_t checksubscr; pthread_mutex_lock(&global_lock); streaming_queue_init(&sq, 0); err = NULL; while(1) { while((t = TAILQ_FIRST(&serviceprobe_queue)) == NULL) { if(was_doing_work) { tvhlog(LOG_INFO, "serviceprobe", "Now idle"); was_doing_work = 0; } pthread_cond_wait(&serviceprobe_cond, &global_lock); } if(!was_doing_work) { tvhlog(LOG_INFO, "serviceprobe", "Starting"); was_doing_work = 1; } if (t->s_dvb_mux_instance) checksubscr = !t->s_dvb_mux_instance->tdmi_adapter->tda_skip_checksubscr; else checksubscr = 1; if (checksubscr) { tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...", t->s_svcname); s = subscription_create_from_service(t, "serviceprobe", &sq.sq_st, 0, NULL, NULL, "serviceprobe"); if(s == NULL) { t->s_sp_onqueue = 0; TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); tvhlog(LOG_INFO, "serviceprobe", "%20s: could not subscribe", t->s_svcname); continue; } } service_ref(t); pthread_mutex_unlock(&global_lock); if (checksubscr) { run = 1; pthread_mutex_lock(&sq.sq_mutex); while(run) { while((sm = TAILQ_FIRST(&sq.sq_queue)) == NULL) pthread_cond_wait(&sq.sq_cond, &sq.sq_mutex); TAILQ_REMOVE(&sq.sq_queue, sm, sm_link); pthread_mutex_unlock(&sq.sq_mutex); if(sm->sm_type == SMT_SERVICE_STATUS) { int status = sm->sm_code; if(status & TSS_PACKETS) { run = 0; err = NULL; } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { run = 0; err = service_tss2text(status); } } streaming_msg_free(sm); pthread_mutex_lock(&sq.sq_mutex); } streaming_queue_clear(&sq.sq_queue); pthread_mutex_unlock(&sq.sq_mutex); } else { err = NULL; } pthread_mutex_lock(&global_lock); if (checksubscr) { subscription_unsubscribe(s); } if(t->s_status != SERVICE_ZOMBIE) { if(err != NULL) { tvhlog(LOG_INFO, "serviceprobe", "%20s: skipped: %s", t->s_svcname, err); } else if(t->s_ch == NULL) { int channum = t->s_channel_number; const char *str; if (!channum && t->s_dvb_mux_instance->tdmi_adapter->tda_sidtochan) channum = t->s_dvb_service_id; ch = channel_find_by_name(t->s_svcname, 1, channum); service_map_channel(t, ch, 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: mapped to channel \"%s\"", t->s_svcname, t->s_svcname); if(service_is_tv(t)) { channel_tag_map(ch, channel_tag_find_by_name("TV channels", 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", t->s_svcname, "TV channels"); } switch(t->s_servicetype) { case ST_SDTV: case ST_AC_SDTV: case ST_EX_SDTV: case ST_DN_SDTV: case ST_SK_SDTV: case ST_NE_SDTV: str = "SDTV"; break; case ST_HDTV: case ST_AC_HDTV: case ST_EX_HDTV: case ST_EP_HDTV: case ST_ET_HDTV: case ST_DN_HDTV: str = "HDTV"; break; case ST_RADIO: str = "Radio"; break; default: str = NULL; } if(str != NULL) { channel_tag_map(ch, channel_tag_find_by_name(str, 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", t->s_svcname, str); } if(t->s_provider != NULL) { channel_tag_map(ch, channel_tag_find_by_name(t->s_provider, 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", t->s_svcname, t->s_provider); } channel_save(ch); } t->s_sp_onqueue = 0; TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); } service_unref(t); } return NULL; }