Ejemplo n.º 1
0
static void *
mtimer_thread(void *aux)
{
  mtimer_t *mti;
  mti_callback_t *cb;
  int64_t now, next;
  const char *id;

  pthread_mutex_lock(&global_lock);
  while (tvheadend_is_running() && atomic_get(&tvheadend_mainloop) == 0)
    tvh_cond_wait(&mtimer_cond, &global_lock);
  pthread_mutex_unlock(&global_lock);

  while (tvheadend_is_running()) {
    now = mdispatch_clock_update();

    /* Global monoclock timers */
    pthread_mutex_lock(&global_lock);

    next = now + sec2mono(3600);

    while((mti = LIST_FIRST(&mtimers)) != NULL) {

      if (mti->mti_expire > now) {
        next = mti->mti_expire;
        break;
      }

#if ENABLE_GTIMER_CHECK
      id = mti->mti_id;
#else
      id = NULL;
#endif
      tprofile_start(&mtimer_profile, id);

      cb = mti->mti_callback;

      LIST_REMOVE(mti, mti_link);
      mti->mti_callback = NULL;

      cb(mti->mti_opaque);

      tprofile_finish(&mtimer_profile);
    }

    /* Periodic updates */
    if (next > mtimer_periodic)
      next = mtimer_periodic;

    /* Wait */
    tvh_cond_timedwait(&mtimer_cond, &global_lock, next);
    pthread_mutex_unlock(&global_lock);
  }

  return NULL;
}
Ejemplo n.º 2
0
static void *
mtimer_thread(void *aux)
{
  mtimer_t *mti;
  mti_callback_t *cb;
  int64_t now, next;
#if ENABLE_GTIMER_CHECK
  int64_t mtm;
  const char *id;
  const char *fcn;
#endif

  while (tvheadend_is_running()) {
    now = mdispatch_clock_update();

    /* Global monoclock timers */
    pthread_mutex_lock(&global_lock);

    next = now + sec2mono(3600);

    while((mti = LIST_FIRST(&mtimers)) != NULL) {
      
      if (mti->mti_expire > now) {
        next = mti->mti_expire;
        break;
      }

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock();
      id = mti->mti_id;
      fcn = mti->mti_fcn;
#endif
      cb = mti->mti_callback;

      LIST_REMOVE(mti, mti_link);
      mti->mti_callback = NULL;

      cb(mti->mti_opaque);

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock() - mtm;
      if (mtm > 10000)
        tvhtrace("mtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm);
#endif
    }

    /* Periodic updates */
    if (next > mtimer_periodic)
      next = mtimer_periodic;

    /* Wait */
    tvh_cond_timedwait(&mtimer_cond, &global_lock, next);
    pthread_mutex_unlock(&global_lock);
  }
  
  return NULL;
}
Ejemplo n.º 3
0
static void *
mtimer_tick_thread(void *aux)
{
  while (tvheadend_is_running()) {
    /* update clocks each 10x in one second */
    atomic_set_s64(&__mdispatch_clock, getmonoclock());
    tvh_safe_usleep(100000);
  }
  return NULL;
}
Ejemplo n.º 4
0
static void
mainloop(void)
{
  gtimer_t *gti;
  gti_callback_t *cb;
  time_t now;
  struct timespec ts;
  const char *id;

  while (tvheadend_is_running()) {
    now = gdispatch_clock_update();
    ts.tv_sec  = now + 3600;
    ts.tv_nsec = 0;

    /* Global timers */
    pthread_mutex_lock(&global_lock);

    // TODO: there is a risk that if timers re-insert themselves to
    //       the top of the list with a 0 offset we could loop indefinitely

#if 0
    tvhdebug(LS_GTIMER, "now %"PRItime_t, ts.tv_sec);
    LIST_FOREACH(gti, &gtimers, gti_link)
      tvhdebug(LS_GTIMER, "  gti %p expire %"PRItimet, gti, gti->gti_expire.tv_sec);
#endif

    while((gti = LIST_FIRST(&gtimers)) != NULL) {

      if (gti->gti_expire > now) {
        ts.tv_sec = gti->gti_expire;
        break;
      }

#if ENABLE_GTIMER_CHECK
      id = gti->gti_id;
#else
      id = NULL;
#endif
      tprofile_start(&gtimer_profile, id);

      cb = gti->gti_callback;

      LIST_REMOVE(gti, gti_link);
      gti->gti_callback = NULL;

      cb(gti->gti_opaque);

      tprofile_finish(&gtimer_profile);
    }

    /* Wait */
    pthread_cond_timedwait(&gtimer_cond, &global_lock, &ts);
    pthread_mutex_unlock(&global_lock);
  }
}
Ejemplo n.º 5
0
static void *
tasklet_thread ( void *aux )
{
  tasklet_t *tsk;
  tsk_callback_t *tsk_cb;
  void *opaque;

  tvhthread_renice(20);

  pthread_mutex_lock(&tasklet_lock);
  while (tvheadend_is_running()) {
    tsk = TAILQ_FIRST(&tasklets);
    if (tsk == NULL) {
      tvh_cond_wait(&tasklet_cond, &tasklet_lock);
      continue;
    }
    /* the callback might re-initialize tasklet, save everything */
    TAILQ_REMOVE(&tasklets, tsk, tsk_link);
    tsk_cb = tsk->tsk_callback;
    opaque = tsk->tsk_opaque;
    tsk->tsk_callback = NULL;
    if (tsk->tsk_free) {
      memoryinfo_free(&tasklet_memoryinfo, sizeof(*tsk));
      tsk->tsk_free(tsk);
    }
    /* now, the callback can be safely called */
    if (tsk_cb) {
      pthread_mutex_unlock(&tasklet_lock);
      tsk_cb(opaque, 0);
      pthread_mutex_lock(&tasklet_lock);
    }
  }
  pthread_mutex_unlock(&tasklet_lock);

  return NULL;
}
Ejemplo n.º 6
0
static void *
tvhdhomerun_device_discovery_thread( void *aux )
{
  struct hdhomerun_discover_device_t result_list[MAX_HDHOMERUN_DEVICES];
  int numDevices, brk;

  while (tvheadend_is_running()) {

    numDevices =
      hdhomerun_discover_find_devices_custom(0,
                                             HDHOMERUN_DEVICE_TYPE_TUNER,
                                             HDHOMERUN_DEVICE_ID_WILDCARD,
                                             result_list,
                                             MAX_HDHOMERUN_DEVICES);

    if (numDevices > 0) {
      while (numDevices > 0 ) {
        numDevices--;
        struct hdhomerun_discover_device_t* cDev = &result_list[numDevices];
        if ( cDev->device_type == HDHOMERUN_DEVICE_TYPE_TUNER ) {
          pthread_mutex_lock(&global_lock);
          tvhdhomerun_device_t *existing = tvhdhomerun_device_find(cDev->device_id);
          if ( tvheadend_is_running() ) {
            if ( !existing ) {
              tvhinfo(LS_TVHDHOMERUN,"Found HDHomerun device %08x with %d tuners",
                      cDev->device_id, cDev->tuner_count);
              tvhdhomerun_device_create(cDev);
            } else if ( ((struct sockaddr_in *)&existing->hd_info.ip_address)->sin_addr.s_addr !=
                     htonl(cDev->ip_addr) ) {
              struct sockaddr_storage detected_dev_addr;
              memset(&detected_dev_addr, 0, sizeof(detected_dev_addr));
              detected_dev_addr.ss_family = AF_INET;
              ((struct sockaddr_in *)&detected_dev_addr)->sin_addr.s_addr = htonl(cDev->ip_addr);

              char existing_ip[64];
              tcp_get_str_from_ip(&existing->hd_info.ip_address, existing_ip, sizeof(existing_ip));

              char detected_ip[64];
              tcp_get_str_from_ip(&detected_dev_addr, detected_ip, sizeof(detected_ip));

              tvhinfo(LS_TVHDHOMERUN,"HDHomerun device %08x switched IPs from %s to %s, updating",
                     cDev->device_id, existing_ip, detected_ip);
              tvhdhomerun_device_destroy(existing);
              tvhdhomerun_device_create(cDev);
            }
          }
          pthread_mutex_unlock(&global_lock);
        }
      }
    }

    pthread_mutex_lock(&tvhdhomerun_discovery_lock);
    brk = 0;
    if (tvheadend_is_running()) {
      brk = tvh_cond_timedwait(&tvhdhomerun_discovery_cond,
                               &tvhdhomerun_discovery_lock,
                               mclk() + sec2mono(15));
      brk = !ERRNO_AGAIN(brk) && brk != ETIMEDOUT;
    }
    pthread_mutex_unlock(&tvhdhomerun_discovery_lock);
    if (brk)
      break;
  }

  return NULL;
}
Ejemplo n.º 7
0
static void
mainloop(void)
{
  gtimer_t *gti;
  gti_callback_t *cb;
  time_t now;
  struct timespec ts;
#if ENABLE_GTIMER_CHECK
  int64_t mtm;
  const char *id;
  const char *fcn;
#endif

  while (tvheadend_is_running()) {
    now = gdispatch_clock_update();
    ts.tv_sec  = now + 3600;
    ts.tv_nsec = 0;

    /* Global timers */
    pthread_mutex_lock(&global_lock);

    // TODO: there is a risk that if timers re-insert themselves to
    //       the top of the list with a 0 offset we could loop indefinitely
    
#if 0
    tvhdebug("gtimer", "now %"PRItime_t, ts.tv_sec);
    LIST_FOREACH(gti, &gtimers, gti_link)
      tvhdebug("gtimer", "  gti %p expire %"PRItimet, gti, gti->gti_expire.tv_sec);
#endif

    while((gti = LIST_FIRST(&gtimers)) != NULL) {
      
      if (gti->gti_expire > now) {
        ts.tv_sec = gti->gti_expire;
        break;
      }

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock();
      id = gti->gti_id;
      fcn = gti->gti_fcn;
#endif
      cb = gti->gti_callback;

      LIST_REMOVE(gti, gti_link);
      gti->gti_callback = NULL;

      cb(gti->gti_opaque);

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock() - mtm;
      if (mtm > 10000)
        tvhtrace("gtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm);
#endif
    }

    /* Wait */
    pthread_cond_timedwait(&gtimer_cond, &global_lock, &ts);
    pthread_mutex_unlock(&global_lock);
  }
}
Ejemplo n.º 8
0
static void *
linuxdvb_ca_en50221_thread ( void *aux )
{
  linuxdvb_ca_t *lca = aux;
  int slot_id, lasterror = 0;

  lca->lca_tl = en50221_tl_create(5, 32);
  if (!lca->lca_tl) {
    tvherror(LS_EN50221, "failed to create transport layer");
    return NULL;
  }

  slot_id = en50221_tl_register_slot(lca->lca_tl, lca->lca_ca_fd, 0, 1000, 100);
  if (slot_id < 0) {
    tvherror(LS_EN50221, "slot registration failed");
    return NULL;
  }

  lca->lca_sl = en50221_sl_create(lca->lca_tl, 256);
  if (lca->lca_sl == NULL) {
    tvherror(LS_EN50221, "failed to create session layer");
    return NULL;
  }

  // create the sendfuncs
  lca->lca_sf.arg        = lca->lca_sl;
  lca->lca_sf.send_data  = (en50221_send_data) en50221_sl_send_data;
  lca->lca_sf.send_datav = (en50221_send_datav) en50221_sl_send_datav;

  /* create app resources and assign callbacks */
  lca->lca_rm_resource = en50221_app_rm_create(&lca->lca_sf);
  en50221_app_rm_register_enq_callback(lca->lca_rm_resource, linuxdvb_ca_rm_enq_cb, lca);
  en50221_app_rm_register_reply_callback(lca->lca_rm_resource, linuxdvb_ca_rm_reply_cb, lca);
  en50221_app_rm_register_changed_callback(lca->lca_rm_resource, linuxdvb_ca_rm_changed_cb, lca);

  lca->lca_dt_resource = en50221_app_datetime_create(&lca->lca_sf);
  en50221_app_datetime_register_enquiry_callback(lca->lca_dt_resource, linuxdvb_ca_dt_enquiry_cb, lca);

  lca->lca_ai_resource = en50221_app_ai_create(&lca->lca_sf);
  en50221_app_ai_register_callback(lca->lca_ai_resource, linuxdvb_ca_ai_callback, lca);

  lca->lca_ca_resource = en50221_app_ca_create(&lca->lca_sf);
  en50221_app_ca_register_info_callback(lca->lca_ca_resource, linuxdvb_ca_ca_info_callback, lca);
  en50221_app_ca_register_pmt_reply_callback(lca->lca_ca_resource, linuxdvb_ca_ca_pmt_reply_cb, lca);

  lca->lca_mmi_resource = en50221_app_mmi_create(&lca->lca_sf);
  en50221_app_mmi_register_close_callback(lca->lca_mmi_resource, linuxdvb_ca_mmi_close_cb, lca);
  en50221_app_mmi_register_display_control_callback(lca->lca_mmi_resource, linuxdvb_ca_mmi_display_ctl_cb, lca);
  en50221_app_mmi_register_enq_callback(lca->lca_mmi_resource, linuxdvb_ca_mmi_enq_cb, lca);
  en50221_app_mmi_register_menu_callback(lca->lca_mmi_resource, linuxdvb_ca_mmi_menu_cb, lca);
  en50221_app_mmi_register_list_callback(lca->lca_mmi_resource, linuxdvb_ca_app_mmi_list_cb, lca);

  en50221_sl_register_lookup_callback(lca->lca_sl, linuxdvb_ca_lookup_cb, lca);
  en50221_sl_register_session_callback(lca->lca_sl, linuxdvb_ca_session_cb, lca);

  lca->lca_tc = en50221_tl_new_tc(lca->lca_tl, slot_id);

  while (tvheadend_is_running() && lca->lca_en50221_thread_running) {
        int error;
        if ((error = en50221_tl_poll(lca->lca_tl)) != 0) {
            if (error != lasterror) {
                tvherror(LS_EN50221, "poll error on slot %d [error:%i]",
                        en50221_tl_get_error_slot(lca->lca_tl),
                        en50221_tl_get_error(lca->lca_tl));
            }
            lasterror = error;
        }
  }

  dvbcam_unregister_cam(lca, 0);

  en50221_tl_destroy_slot(lca->lca_tl, slot_id);
  en50221_sl_destroy(lca->lca_sl);
  en50221_tl_destroy(lca->lca_tl);
  return 0;
}