Example #1
0
void
streaming_queue_deinit(streaming_queue_t *sq)
{
  streaming_queue_clear(&sq->sq_queue);
  pthread_mutex_destroy(&sq->sq_mutex);
  pthread_cond_destroy(&sq->sq_cond);
}
Example #2
0
void
timeshift_destroy(streaming_target_t *pad)
{
  timeshift_t *ts = (timeshift_t*)pad;
  streaming_message_t *sm;
  int i;

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Ensure the threads exits */
  // Note: this is a workaround for the fact the Q might have been flushed
  //       in reader thread (VERY unlikely)
  pthread_mutex_lock(&ts->state_mutex);
  sm = streaming_msg_create(SMT_EXIT);
  streaming_target_deliver2(&ts->wr_queue.sq_st, sm);
  timeshift_write_exit(ts->rd_pipe.wr);
  pthread_mutex_unlock(&ts->state_mutex);

  /* Wait for all threads */
  pthread_join(ts->rd_thread, NULL);
  pthread_join(ts->wr_thread, NULL);

  /* Shut stuff down */
  streaming_queue_deinit(&ts->wr_queue);
  for (i = 0; i < TIMESHIFT_BACKLOG_MAX; i++)
    streaming_queue_clear(&ts->backlog[i]);

  close(ts->rd_pipe.rd);
  close(ts->rd_pipe.wr);

  /* Flush files */
  timeshift_filemgr_flush(ts, NULL);

  /* Release SMT_START index */
  if (ts->smt_start)
    streaming_start_unref(ts->smt_start);

  if (ts->path)
    free(ts->path);
  free(ts);
}
Example #3
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;
}