}
#endif
-extern int64_t mdispatch_clock;
-extern time_t gdispatch_clock;
+extern int64_t __mdispatch_clock;
+extern time_t __gdispatch_clock;
+
+static inline int64_t mclk(void)
+{
+ return atomic_add_s64(&__mdispatch_clock, 0);
+}
+
+static inline time_t gclk(void)
+{
+ return atomic_add_time_t(&__gdispatch_clock, 0);
+}
#define MONOCLOCK_RESOLUTION 1000000LL /* microseconds */
(tp.tv_nsec / (1000000000LL/MONOCLOCK_RESOLUTION));
}
-time_t gdispatch_clock_update(void);
-int64_t mdispatch_clock_update(void);
-
void time_t_out_of_range_notify(int64_t val);
static inline time_t time_t_out_of_range(uint64_t val)
tvhlog(LOG_INFO, "capmt", "%s: Automatic reconnection attempt in in %d seconds", idnode_get_title(&capmt->cac_id, NULL), d);
- mono = mdispatch_clock + sec2mono(d);
+ mono = mclk() + sec2mono(d);
do {
i = tvh_cond_timedwait(&capmt->capmt_cond, &capmt->capmt_mutex, mono);
if (i == ETIMEDOUT)
/* If nothing is to be sent in CWC_KEEPALIVE_INTERVAL seconds we
need to send a keepalive */
- mono = mdispatch_clock + sec2mono(CWC_KEEPALIVE_INTERVAL);
+ mono = mclk() + sec2mono(CWC_KEEPALIVE_INTERVAL);
do {
r = tvh_cond_timedwait(&cwc->cwc_writer_cond, &cwc->cwc_writer_mutex, mono);
if(r == ETIMEDOUT) {
"%s:%i: Automatic connection attempt in %d seconds",
cwc->cwc_hostname, cwc->cwc_port, d-1);
- mono = mdispatch_clock + sec2mono(d);
+ mono = mclk() + sec2mono(d);
do {
r = tvh_cond_timedwait(&cwc->cwc_cond, &cwc->cwc_mutex, mono);
if (r == ETIMEDOUT)
if (pcard->running && cwc->cwc_forward_emm && cwc->cwc_writer_running) {
if (cwc->cwc_emmex) {
if (cwc->cwc_mux != mux) {
- if (cwc->cwc_update_time + sec2mono(25) < mdispatch_clock)
+ if (cwc->cwc_update_time + sec2mono(25) < mclk())
goto end_of_job;
}
- cwc->cwc_update_time = mdispatch_clock;
+ cwc->cwc_update_time = mclk();
}
cwc->cwc_mux = mux;
emm_filter(&pcard->cs_ra, data, len, mux, cwc_emm_send, pcard);
if (len == 0)
return;
dd = TAILQ_LAST(&dr->dr_queue, th_descrambler_queue);
- if (dd && mono2sec(dd->dd_timestamp) == mono2sec(mdispatch_clock) &&
+ if (dd && mono2sec(dd->dd_timestamp) == mono2sec(mclk()) &&
(dd->dd_sbuf.sb_data[3] & 0x40) == (tsb[3] & 0x40)) { /* key match */
sbuf_append(&dd->dd_sbuf, tsb, len);
dr->dr_queue_total += len;
return;
}
dd = malloc(sizeof(*dd));
- dd->dd_timestamp = mdispatch_clock;
+ dd->dd_timestamp = mclk();
sbuf_init(&dd->dd_sbuf);
sbuf_append(&dd->dd_sbuf, tsb, len);
TAILQ_INSERT_TAIL(&dr->dr_queue, dd, dd_link);
memcpy(dr->dr_key_even, even, dr->dr_csa.csa_keylen);
dr->dr_key_changed |= 1;
dr->dr_key_valid |= 0x40;
- dr->dr_key_timestamp[0] = mdispatch_clock;
+ dr->dr_key_timestamp[0] = mclk();
}
if (memcmp(empty, odd, dr->dr_csa.csa_keylen)) {
j++;
memcpy(dr->dr_key_odd, odd, dr->dr_csa.csa_keylen);
dr->dr_key_changed |= 2;
dr->dr_key_valid |= 0x80;
- dr->dr_key_timestamp[1] = mdispatch_clock;
+ dr->dr_key_timestamp[1] = mclk();
}
if (j) {
tvhtrace("descrambler", "Unknown keys from %s for for service \"%s\"",
td->td_nicename, ((mpegts_service_t *)t)->s_dvb_svcname);
}
- dr->dr_ecm_last_key_time = mdispatch_clock;
+ dr->dr_ecm_last_key_time = mclk();
td->td_keystate = DS_RESOLVED;
td->td_service->s_descrambler = td;
} else {
key_started( th_descrambler_runtime_t *dr, uint8_t ki )
{
uint8_t kidx = (ki & 0x40) >> 6;
- return mdispatch_clock - dr->dr_ecm_start[kidx] < sec2mono(5);
+ return mclk() - dr->dr_ecm_start[kidx] < sec2mono(5);
}
static int
/* process the queued TS packets */
if (dr->dr_queue_total > 0) {
- descrambler_data_time_flush(dr, mdispatch_clock - (dr->dr_key_interval - sec2mono(2)));
+ descrambler_data_time_flush(dr, mclk() - (dr->dr_key_interval - sec2mono(2)));
for (dd = TAILQ_FIRST(&dr->dr_queue); dd; dd = dd_next) {
dd_next = TAILQ_NEXT(dd, dd_link);
sb = &dd->dd_sbuf;
"even stream key is not valid");
goto next;
}
- if (key_changed(dr, ki, mdispatch_clock)) {
+ if (key_changed(dr, ki, mclk())) {
tvhtrace("descrambler", "stream key changed to %s for service \"%s\"",
(ki & 0x40) ? "odd" : "even",
((mpegts_service_t *)t)->s_dvb_svcname);
- if (key_late(dr, ki, mdispatch_clock)) {
+ if (key_late(dr, ki, mclk())) {
tvherror("descrambler", "ECM - key late (%ld ms) for service \"%s\"",
- mono2ms(mdispatch_clock - dr->dr_ecm_last_key_time),
+ mono2ms(mclk() - dr->dr_ecm_last_key_time),
((mpegts_service_t *)t)->s_dvb_svcname);
descrambler_notify_nokey(dr);
if (ecm_reset(t, dr)) {
goto next;
}
}
- key_update(dr, ki, mdispatch_clock);
+ key_update(dr, ki, mclk());
}
}
dr->dr_skip = 1;
tvhtrace("descrambler", "initial stream key set to %s for service \"%s\"",
(ki & 0x40) ? "odd" : "even",
((mpegts_service_t *)t)->s_dvb_svcname);
- key_update(dr, ki, mdispatch_clock);
+ key_update(dr, ki, mclk());
break;
} else {
descrambler_data_cut(dr, 188);
}
}
} else if (dr->dr_key_index != (ki & 0x40) &&
- dr->dr_key_start + sec2mono(2) < mdispatch_clock) {
+ dr->dr_key_start + sec2mono(2) < mclk()) {
tvhtrace("descrambler", "stream key changed to %s for service \"%s\"",
(ki & 0x40) ? "odd" : "even",
((mpegts_service_t *)t)->s_dvb_svcname);
- key_update(dr, ki, mdispatch_clock);
+ key_update(dr, ki, mclk());
}
}
if (count != failed) {
dbuflen = MAX(300, config.descrambler_buffer);
if (dr->dr_queue_total >= dbuflen * 188) {
descrambler_data_cut(dr, MAX((dbuflen / 10) * 188, len));
- if (dr->dr_last_err + sec2mono(10) < mdispatch_clock) {
- dr->dr_last_err = mdispatch_clock;
+ if (dr->dr_last_err + sec2mono(10) < mclk()) {
+ dr->dr_last_err = mclk();
tvherror("descrambler", "cannot decode packets for service \"%s\"",
((mpegts_service_t *)t)->s_dvb_svcname);
} else {
t->s_dvb_svcname);
}
if ((ptr[0] & 0xfe) == 0x80) { /* 0x80 = even, 0x81 = odd */
- dr->dr_ecm_start[ptr[0] & 1] = mdispatch_clock;
+ dr->dr_ecm_start[ptr[0] & 1] = mclk();
if (dr->dr_quick_ecm)
dr->dr_key_valid &= ~(1 << ((ptr[0] & 1) + 6)); /* 0x40 = even, 0x80 = odd */
}
if (de->de_sched_state != DVR_SCHEDULED)
continue;
start = dvr_entry_get_start_time(de, 1);
- if (gdispatch_clock < start && start > max)
+ if (gclk() < start && start > max)
max = start;
}
/* lower the maximum value */
if (de->de_sched_state != DVR_SCHEDULED)
continue;
start = dvr_entry_get_start_time(de, 1);
- if (gdispatch_clock < start && start < result)
+ if (gclk() < start && start < result)
result = start;
}
/* different? send it.... */
dvr_entry_retention_arm(dvr_entry_t *de, gti_callback_t *cb, time_t when)
{
uint32_t rerecord = dvr_entry_get_rerecord_errors(de);
- if (rerecord && (when - gdispatch_clock) > 3600) {
- when = gdispatch_clock + 3600;
+ if (rerecord && (when - gclk()) > 3600) {
+ when = gclk() + 3600;
cb = dvr_timer_rerecord;
}
gtimer_arm_absn(&de->de_timer, cb, de, when);
stop = time_t_out_of_range((int64_t)de->de_stop + removal * (int64_t)86400);
if ((removal > 0 || retention == 0) && removal < DVR_RET_SPACE) {
- if (stop > gdispatch_clock) {
+ if (stop > gclk()) {
dvr_entry_retention_arm(de, dvr_timer_remove_files, stop);
return;
}
/* EPG thinks that the program is running */
if(de->de_running_start > de->de_running_stop && !de->de_dont_reschedule) {
- stop = gdispatch_clock + 10;
+ stop = gclk() + 10;
if (de->de_sched_state == DVR_RECORDING)
goto recording;
}
if(de->de_sched_state == DVR_RECORDING) {
dvr_stop_recording(de, SM_CODE_SOURCE_RECONFIGURED, 1, 1);
dvr_rec_migrate(de, n);
- n->de_start = gdispatch_clock;
+ n->de_start = gclk();
dvr_entry_start_recording(n, 1);
} else {
dvr_entry_set_timer(n);
dvr_entry_warm_time(de);
RB_FOREACH(ev, &de->de_channel->ch_epg_schedule, sched_link) {
if (de->de_bcast == ev) continue;
- if (ev->start - pre < gdispatch_clock) continue;
+ if (ev->start - pre < gclk()) continue;
if (dvr_entry_fuzzy_match(de, ev, 0, INT64_MAX))
if (!e || e->start > ev->start)
e = ev;
if (!dvr_entry_is_editable(de)) {
if (stop > 0) {
- if (stop < gdispatch_clock)
- stop = gdispatch_clock;
+ if (stop < gclk())
+ stop = gclk();
if (stop < de->de_start)
stop = de->de_start;
if (stop != de->de_stop) {
idnode_uuid_as_str(&de->de_id, ubuf),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
- atomic_exchange_time_t(&de->de_running_start, gdispatch_clock);
+ atomic_exchange_time_t(&de->de_running_start, gclk());
}
- if (dvr_entry_get_start_time(de, 1) > gdispatch_clock) {
- atomic_exchange_time_t(&de->de_start, gdispatch_clock);
+ if (dvr_entry_get_start_time(de, 1) > gclk()) {
+ atomic_exchange_time_t(&de->de_start, gclk());
dvr_entry_set_timer(de);
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start",
idnode_uuid_as_str(&de->de_id, ubuf),
* sometimes, the running bits are parsed randomly for a few moments
* so don't expect that the broacasting has only 5 seconds
*/
- if (de->de_running_start + 5 > gdispatch_clock)
+ if (de->de_running_start + 5 > gclk())
continue;
srcname = de->de_dvb_eid == e->dvb_eid ? "event" : "other running event";
epg_broadcast_get_title(e, NULL),
channel_get_name(de->de_channel));
}
- atomic_exchange_time_t(&de->de_running_stop, gdispatch_clock);
+ atomic_exchange_time_t(&de->de_running_stop, gclk());
atomic_exchange_time_t(&de->de_running_pause, 0);
if (de->de_sched_state == DVR_RECORDING && de->de_running_start) {
dvr_stop_recording(de, SM_CODE_OK, 0, 0);
idnode_uuid_as_str(&de->de_id, ubuf),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
- atomic_exchange_time_t(&de->de_running_pause, gdispatch_clock);
+ atomic_exchange_time_t(&de->de_running_pause, gclk());
}
}
}
time_t v = *(time_t *)_v;
if (!dvr_entry_is_editable(de)) {
- if (v < gdispatch_clock)
- v = gdispatch_clock;
+ if (v < gclk())
+ v = gclk();
}
if (v < de->de_start)
v = de->de_start;
static void
dvr_notify(dvr_entry_t *de)
{
- if (de->de_last_notify + sec2mono(5) < mdispatch_clock) {
+ if (de->de_last_notify + sec2mono(5) < mclk()) {
idnode_notify_changed(&de->de_id);
- de->de_last_notify = mdispatch_clock;
+ de->de_last_notify = mclk();
htsp_dvr_entry_update(de);
}
}
streaming_queue_remove(sq, sm);
if (running_disabled) {
- epg_running = real_start <= gdispatch_clock;
+ epg_running = real_start <= gclk();
} else if (sm->sm_type == SMT_PACKET || sm->sm_type == SMT_MPEGTS) {
running_start = atomic_add_time_t(&de->de_running_start, 0);
running_stop = atomic_add_time_t(&de->de_running_stop, 0);
if (epg_running && atomic_add_time_t(&de->de_running_pause, 0) >= running_start)
epg_running = 2;
} else if (running_stop == 0) {
- if (start_time + 2 >= gdispatch_clock) {
+ if (start_time + 2 >= gclk()) {
TAILQ_INSERT_TAIL(&backlog, sm, sm_link);
continue;
} else {
if (TAILQ_FIRST(&backlog))
streaming_queue_clear(&backlog);
- epg_running = real_start <= gdispatch_clock;
+ epg_running = real_start <= gclk();
}
} else {
epg_running = 0;
break;
case SMT_START:
- start_time = gdispatch_clock;
+ start_time = gclk();
packets = 0;
if (ss)
streaming_start_unref(ss);
if(dte->dte_channel == NULL)
goto fail;
- limit = gdispatch_clock - 600;
- start = dvr_timerec_timecorrection(gdispatch_clock, dte->dte_start, &tm_start);
- stop = dvr_timerec_timecorrection(gdispatch_clock, dte->dte_stop, &tm_stop);
+ limit = gclk() - 600;
+ start = dvr_timerec_timecorrection(gclk(), dte->dte_start, &tm_start);
+ stop = dvr_timerec_timecorrection(gclk(), dte->dte_stop, &tm_stop);
if (start < limit && stop < limit) {
/* next day */
- start = dvr_timerec_timecorrection(gdispatch_clock + 24*60*60,
+ start = dvr_timerec_timecorrection(gclk() + 24*60*60,
dte->dte_start,
&tm_start);
- stop = dvr_timerec_timecorrection(gdispatch_clock + 24*60*60,
+ stop = dvr_timerec_timecorrection(gclk() + 24*60*60,
dte->dte_stop,
&tm_stop);
}
/* When deleting a file from the disk, the system needs some time to actually do this */
/* If calling this function to fast after the previous call, statvfs might be wrong/not updated yet */
/* So we are risking to delete more files than needed, so allow 10s for the system to handle previous deletes */
- if (dvr_disk_space_config_lastdelete + sec2mono(10) > mdispatch_clock) {
+ if (dvr_disk_space_config_lastdelete + sec2mono(10) > mclk()) {
tvhlog(LOG_WARNING, "dvr","disk space cleanup for config \"%s\" is not allowed now", configName);
return -1;
}
while (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) {
oldest = NULL;
- stoptime = gdispatch_clock;
+ stoptime = gclk();
LIST_FOREACH(de, &dvrentries, de_global_link) {
if (de->de_sched_state != DVR_COMPLETED &&
tvhlog(LOG_INFO, "dvr","Delete \"until space needed\" recording \"%s\" with stop time \"%s\" and file size \"%"PRId64" MB\"",
lang_str_get(oldest->de_title, NULL), tbuf, TOMIB(fileSize));
- dvr_disk_space_config_lastdelete = mdispatch_clock;
+ dvr_disk_space_config_lastdelete = mclk();
if (dvr_entry_get_retention_days(oldest) == DVR_RET_ONREMOVE) {
dvr_entry_delete(oldest); // delete actual file
dvr_entry_destroy(oldest, 1); // also delete database entry
tvhtrace("epg", "eo [%p, %u, %d, %s] updated",
eo, eo->id, eo->type, eo->uri);
eo->_updated = 1;
- eo->updated = gdispatch_clock;
+ eo->updated = gclk();
LIST_INSERT_HEAD(&epg_object_updated, eo, up_link);
}
}
while ((ebc = RB_FIRST(&ch->ch_epg_schedule))) {
/* Expire */
- if ( ebc->stop <= gdispatch_clock ) {
+ if ( ebc->stop <= gclk() ) {
tvhlog(LOG_DEBUG, "epg", "expire event %u (%s) from %s",
ebc->id, epg_broadcast_get_title(ebc, NULL),
channel_get_name(ch));
continue; // skip to next
/* No now */
- } else if (ebc->start > gdispatch_clock) {
+ } else if (ebc->start > gclk()) {
ch->ch_epg_next = ebc;
next = ebc->start;
epg_broadcast_t **ebc;
if (!channel || !start || !stop) return NULL;
if (stop <= start) return NULL;
- if (stop <= gdispatch_clock) return NULL;
+ if (stop <= gclk()) return NULL;
ebc = _epg_broadcast_skel();
(*ebc)->start = start;
now = ch ? ch->ch_epg_now : NULL;
if (running == EPG_RUNNING_STOP) {
if (now == broadcast && orunning == broadcast->running)
- broadcast->stop = gdispatch_clock - 1;
+ broadcast->stop = gclk() - 1;
} else {
if (broadcast != now && now) {
now->running = EPG_RUNNING_STOP;
if (htsmsg_get_s64(m, "stop", &stop)) return NULL;
if (!start || !stop) return NULL;
if (stop <= start) return NULL;
- if (stop <= gdispatch_clock) return NULL;
+ if (stop <= gclk()) return NULL;
if (!(str = htsmsg_get_str(m, "episode"))) return NULL;
_epg_object_deserialize(m, (epg_object_t*)*skel);
/* Filtering */
if (e == NULL) return;
- if (e->stop < gdispatch_clock) return;
+ if (e->stop < gclk()) return;
if (_eq_comp_num(&eq->start, e->start)) return;
if (_eq_comp_num(&eq->stop, e->stop)) return;
if (eq->duration.comp != EC_NO) {
}
ps->ps_refcount++;
mt->mt_destroy = psip_status_destroy;
- pt->pt_start = mdispatch_clock;
+ pt->pt_start = mclk();
pt->pt_table = mt;
tvhtrace("psip", "table activated - pid 0x%04X type 0x%04X", mt->mt_pid, pt->pt_type);
return mt;
total = 0;
TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) {
total++;
- if (pt->pt_table && pt->pt_start + sec2mono(10) < mdispatch_clock) {
+ if (pt->pt_table && pt->pt_start + sec2mono(10) < mclk()) {
tvhtrace("psip", "table late: pid = 0x%04X, type = 0x%04X\n", pt->pt_pid, pt->pt_type);
mpegts_table_destroy(pt->pt_table);
pt->pt_table = NULL;
HTSMSG_FOREACH(f, tags) {
if (strcmp(f->hmf_name, "broadcast") == 0) {
- ec->laststamp = gdispatch_clock;
+ ec->laststamp = gclk();
LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) {
ch = (channel_t *)ilm->ilm_in2;
if (!ch->ch_enabled || ch->ch_epg_parent) continue;
(attribs = htsmsg_get_map(subtag, "attrib")) != NULL)
icon = htsmsg_get_str(attribs, "src");
- if(stop <= start || stop <= gdispatch_clock) return 0;
+ if(stop <= start || stop <= gclk()) return 0;
- ec->laststamp = gdispatch_clock;
+ ec->laststamp = gclk();
LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) {
ch = (channel_t *)ilm->ilm_in2;
if (!ch->ch_enabled || ch->ch_epg_parent) continue;
if((id = htsmsg_get_str(attribs, "id")) == NULL) return 0;
if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0;
if((ch = epggrab_channel_find(mod, id, 1, &save)) == NULL) return 0;
- ch->laststamp = gdispatch_clock;
+ ch->laststamp = gclk();
stats->channels.total++;
if (save) stats->channels.created++;
epggrab_ota_kick(1);
pthread_mutex_lock(&epggrab_ota_mutex);
- if (!cron_multi_next(epggrab_ota_cron_multi, gdispatch_clock, &next))
+ if (!cron_multi_next(epggrab_ota_cron_multi, gclk(), &next))
epggrab_ota_next_arm(next);
else
tvhwarn("epggrab", "ota cron config invalid or unset");
if (htsp->htsp_async_mode & HTSP_ASYNC_EPG) {
/* Only allow to change the window in the correct range */
if (htsp->htsp_epg_window && epgMaxTime > htsp->htsp_epg_lastupdate)
- htsp->htsp_epg_window = epgMaxTime-gdispatch_clock;
- } else if (epgMaxTime > gdispatch_clock) {
- htsp->htsp_epg_window = epgMaxTime-gdispatch_clock;
+ htsp->htsp_epg_window = epgMaxTime-gclk();
+ } else if (epgMaxTime > gclk()) {
+ htsp->htsp_epg_window = epgMaxTime-gclk();
} else {
htsp->htsp_epg_window = 0;
}
channel_t *ch;
int64_t maxtime;
- maxtime = gdispatch_clock + htsp->htsp_epg_window;
+ maxtime = gclk() + htsp->htsp_epg_window;
htsp->htsp_epg_lastupdate = maxtime;
/* Push new events */
htsp_send_subscription(htsp, m, pkt->pkt_payload, hs, payloadlen);
atomic_add(&hs->hs_s_bytes_out, payloadlen);
- if(mono2sec(hs->hs_last_report) != mono2sec(mdispatch_clock)) {
+ if(mono2sec(hs->hs_last_report) != mono2sec(mclk())) {
/* Send a queue and signal status report every second */
- hs->hs_last_report = mdispatch_clock;
+ hs->hs_last_report = mclk();
m = htsmsg_create_map();
htsmsg_add_str(m, "method", "queueStatus");
empty = TAILQ_EMPTY(&hc->hc_wqueue);
TAILQ_INSERT_TAIL(&hc->hc_wqueue, wcmd, link);
- hc->hc_ping_time = mdispatch_clock;
+ hc->hc_ping_time = mclk();
if (empty)
return http_client_send_partial(hc);
return;
ise = malloc(sizeof(*ise));
ise->ise_node = self;
- ise->ise_reqtime = mdispatch_clock;
+ ise->ise_reqtime = mclk();
if (TAILQ_EMPTY(&idnodes_save) && save_running)
mtimer_arm_rel(&save_timer, idnode_save_trigger_thread_cb, NULL, IDNODE_SAVE_DELAY);
TAILQ_INSERT_TAIL(&idnodes_save, ise, ise_link);
while (save_running) {
if ((ise = TAILQ_FIRST(&idnodes_save)) == NULL ||
- (ise->ise_reqtime + IDNODE_SAVE_DELAY > mdispatch_clock)) {
+ (ise->ise_reqtime + IDNODE_SAVE_DELAY > mclk())) {
if (ise)
mtimer_arm_abs(&save_timer, idnode_save_trigger_thread_cb, NULL,
ise->ise_reqtime + IDNODE_SAVE_DELAY);
/* Wait */
} else if (i->state == FETCHING) {
- mono = mdispatch_clock + sec2mono(5);
+ mono = mclk() + sec2mono(5);
do {
e = tvh_cond_timedwait(&imagecache_cond, &global_lock, mono);
if (e == ETIMEDOUT)
s->s_nicename, s->s_dvb_service_id, s->s_dvb_service_id, where);
service_set_enabled((service_t *)s, 1, SERVICE_AUTO_NORMAL);
}
- s->s_dvb_check_seen = gdispatch_clock;
+ s->s_dvb_check_seen = gclk();
}
#if ENABLE_MPEGTS_DVB
{
static time_t dvb_last_update = 0;
time_t t;
- if (dvb_last_update + 1800 < gdispatch_clock) {
+ if (dvb_last_update + 1800 < gclk()) {
t = dvb_convert_date(ptr, 0);
if (t > 0) {
tvhtime_update(t, srcname);
- dvb_last_update = gdispatch_clock;
+ dvb_last_update = gclk();
}
}
}
pthread_mutex_lock(&iptv_lock);
while (!fp->shutdown && fd > 0) {
while (!fp->shutdown && pause) {
- mono = mdispatch_clock + sec2mono(1);
+ mono = mclk() + sec2mono(1);
do {
e = tvh_cond_timedwait(&fp->cond, &iptv_lock, mono);
if (e == ETIMEDOUT)
memcpy(hp->hls_si, buf, 2*188);
}
- if (hp->hls_last_si + sec2mono(1) <= mdispatch_clock && hp->hls_si) {
+ if (hp->hls_last_si + sec2mono(1) <= mclk() && hp->hls_si) {
/* do rounding to start of the last MPEG-TS packet */
rem = 188 - (hp->off % 188);
if (im->mm_iptv_buffer.sb_ptr >= rem) {
im->mm_iptv_buffer.sb_ptr -= rem;
memcpy(tsbuf, im->mm_iptv_buffer.sb_data + im->mm_iptv_buffer.sb_ptr, rem);
sbuf_append(&im->mm_iptv_buffer, hp->hls_si, 2*188);
- hp->hls_last_si = mdispatch_clock;
+ hp->hls_last_si = mclk();
sbuf_append(&im->mm_iptv_buffer, tsbuf, rem);
hp->off += rem;
}
im->mm_iptv_fd = rd;
im->im_data = (void *)(intptr_t)pid;
- im->mm_iptv_respawn_last = mdispatch_clock;
+ im->mm_iptv_respawn_last = mclk();
if (url)
iptv_input_mux_started(im);
spawn_kill(pid, iptv_pipe_kill_sig(im), im->mm_iptv_kill_timeout);
im->mm_iptv_fd = -1;
im->im_data = NULL;
- if (mdispatch_clock < im->mm_iptv_respawn_last + sec2mono(2)) {
+ if (mclk() < im->mm_iptv_respawn_last + sec2mono(2)) {
tvherror("iptv", "stdin pipe unexpectedly closed: %s",
r < 0 ? strerror(errno) : "No data");
} else {
tvherror("iptv", "unable to respawn %s", im->mm_iptv_url_raw);
} else {
iptv_input_fd_started(im);
- im->mm_iptv_respawn_last = mdispatch_clock;
+ im->mm_iptv_respawn_last = mclk();
}
}
pthread_mutex_unlock(&iptv_lock);
lfe, ms2mono(50));
/* Monitor 1 per sec */
- if (mdispatch_clock < lfe->lfe_monitor)
+ if (mclk() < lfe->lfe_monitor)
return;
- lfe->lfe_monitor = mdispatch_clock + sec2mono(1);
+ lfe->lfe_monitor = mclk() + sec2mono(1);
}
} else {
- if (mdispatch_clock < lfe->lfe_monitor)
+ if (mclk() < lfe->lfe_monitor)
return;
- lfe->lfe_monitor = mdispatch_clock + ms2mono(period);
+ lfe->lfe_monitor = mclk() + ms2mono(period);
}
/* Statistics - New API */
if (len < (MIN_TS_PKT * 188) && (flags & MPEGTS_DATA_CC_RESTART) == 0) {
/* For slow streams, check also against the clock */
- if (mono2sec(mdispatch_clock) == mono2sec(mi->mi_last_dispatch))
+ if (mono2sec(mclk()) == mono2sec(mi->mi_last_dispatch))
return;
}
- mi->mi_last_dispatch = mdispatch_clock;
+ mi->mi_last_dispatch = mclk();
/* Check for sync */
while ( (len >= MIN_TS_SYN) &&
dvb_mux_t *lm = (dvb_mux_t*)mm;
/* the nit tables may be inconsistent (like rolloff ping-pong) */
/* accept information only from one origin mux */
- if (mm->mm_dmc_origin_expire > mdispatch_clock && mm->mm_dmc_origin && mm->mm_dmc_origin != origin)
+ if (mm->mm_dmc_origin_expire > mclk() && mm->mm_dmc_origin && mm->mm_dmc_origin != origin)
goto noop;
#define COMPARE(x, cbit) ({ \
int xr = dmc->x != lm->lm_tuning.x; \
save:
if (mm && save) {
mm->mm_dmc_origin = origin;
- mm->mm_dmc_origin_expire = mdispatch_clock + sec2mono(3600 * 24); /* one day */
+ mm->mm_dmc_origin_expire = mclk() + sec2mono(3600 * 24); /* one day */
idnode_changed(&mm->mm_id);
}
noop:
{
int r;
char buf[256];
- time_t dispatch_clock = gdispatch_clock;
+ time_t dispatch_clock = gclk();
/* defaults for older version */
s->s_dvb_created = dispatch_clock;
if (sid) s->s_dvb_service_id = sid;
if (pmt_pid) s->s_pmt_pid = pmt_pid;
} else {
- if (s->s_dvb_last_seen > gdispatch_clock) /* sanity check */
- s->s_dvb_last_seen = gdispatch_clock;
+ if (s->s_dvb_last_seen > gclk()) /* sanity check */
+ s->s_dvb_last_seen = gclk();
}
s->s_dvb_mux = mm;
if ((r = dvb_servicetype_lookup(s->s_dvb_servicetype)) != -1)
if (save) *save = 1;
}
if (create) {
- if ((save && *save) || s->s_dvb_last_seen + 3600 < gdispatch_clock) {
- s->s_dvb_last_seen = gdispatch_clock;
+ if ((save && *save) || s->s_dvb_last_seen + 3600 < gclk()) {
+ s->s_dvb_last_seen = gclk();
if (save) *save = 1;
}
}
/* Create */
if (create) {
s = mm->mm_network->mn_create_service(mm, sid, pmt_pid);
- s->s_dvb_created = s->s_dvb_last_seen = gdispatch_clock;
+ s->s_dvb_created = s->s_dvb_last_seen = gclk();
if (save) *save = 1;
}
d = next;
next = TAILQ_NEXT(d, disc_link);
if (d->http_client) {
- if (mdispatch_clock - d->http_start > sec2mono(4))
+ if (mclk() - d->http_start > sec2mono(4))
satip_discovery_destroy(d, 1);
continue;
}
if (d->http_client == NULL)
satip_discovery_destroy(d, 1);
else {
- d->http_start = mdispatch_clock;
+ d->http_start = mclk();
d->http_client->hc_conn_closed = satip_discovery_http_closed;
http_client_register(d->http_client);
r = http_client_simple(d->http_client, &d->url);
}
if (lfe->sf_sbuf.sb_ptr > 64 * 1024 ||
- lfe->sf_last_data_tstamp + sec2mono(1) <= mdispatch_clock) {
+ lfe->sf_last_data_tstamp + sec2mono(1) <= mclk()) {
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_req == lfe->sf_req_thread) {
mmi = lfe->sf_req->sf_mmi;
&lfe->sf_sbuf, 0, NULL);
}
pthread_mutex_unlock(&lfe->sf_dvr_lock);
- lfe->sf_last_data_tstamp = mdispatch_clock;
+ lfe->sf_last_data_tstamp = mclk();
}
} else if (b[1] == 1) {
}
/* We need to keep the session alive */
- if (rtsp->hc_ping_time + sec2mono(rtsp->hc_rtp_timeout / 2) < mdispatch_clock &&
+ if (rtsp->hc_ping_time + sec2mono(rtsp->hc_rtp_timeout / 2) < mclk() &&
rtsp->hc_cmd == HTTP_CMD_NONE) {
rtsp_options(rtsp);
reply = 1;
cc = tsb2[3] & 0xf;
if(st->es_cc != -1 && cc != st->es_cc) {
/* Let the hardware to stabilize and don't flood the log */
- if (t->s_start_time + sec2mono(1) < mdispatch_clock &&
+ if (t->s_start_time + sec2mono(1) < mclk() &&
tvhlog_limit(&st->es_cc_log, 10))
tvhwarn("TS", "%s Continuity counter error (total %zi)",
service_component_nicename(st), st->es_cc_log.count);
cc = tsb2[3] & 0xf;
if(st->es_cc != -1 && cc != st->es_cc) {
/* Let the hardware to stabilize and don't flood the log */
- if (t->s_start_time + sec2mono(1) < mdispatch_clock &&
+ if (t->s_start_time + sec2mono(1) < mclk() &&
tvhlog_limit(&st->es_cc_log, 10))
tvhwarn("TS", "%s Continuity counter error (total %zi)",
service_component_nicename(st), st->es_cc_log.count);
streaming_message_t sm;
pktbuf_t *pb;
- t->s_tsbuf_last = mdispatch_clock;
+ t->s_tsbuf_last = mclk();
pb = pktbuf_alloc(sb->sb_data, sb->sb_ptr);
pb->pb_err = sb->sb_err;
sbuf_append(sb, src, len);
sb->sb_err += errors;
- if(mono2sec(mdispatch_clock) == mono2sec(t->s_tsbuf_last) &&
+ if(mono2sec(mclk()) == mono2sec(t->s_tsbuf_last) &&
sb->sb_ptr < TS_REMUX_BUFSIZE)
return;
sb->sb_err += len / 188;
- if(mono2sec(mdispatch_clock) == mono2sec(t->s_tsbuf_last) &&
+ if(mono2sec(mclk()) == mono2sec(t->s_tsbuf_last) &&
sb->sb_err < (TS_REMUX_BUFSIZE / 188))
return;
if (tvheadend_running) {
brk = tvh_cond_timedwait(&tvhdhomerun_discovery_cond,
&tvhdhomerun_discovery_lock,
- mdispatch_clock + sec2mono(15));
+ mclk() + sec2mono(15));
brk = !ERRNO_AGAIN(brk) && brk != ETIMEDOUT;
}
pthread_mutex_unlock(&tvhdhomerun_discovery_lock);
pthread_t main_tid;
+int64_t __mdispatch_clock;
+time_t __gdispatch_clock;
+
/* Command line option struct */
typedef struct {
const char sopt;
(GTIMER_TRACEID_ mtimer_t *gti, mti_callback_t *callback, void *opaque, int64_t delta)
{
#if ENABLE_GTIMER_CHECK
- GTIMER_FCN(mtimer_arm_abs)(id, fcn, gti, callback, opaque, mdispatch_clock + delta);
+ GTIMER_FCN(mtimer_arm_abs)(id, fcn, gti, callback, opaque, mclk() + delta);
#else
- mtimer_arm_abs(gti, callback, opaque, mdispatch_clock + delta);
+ mtimer_arm_abs(gti, callback, opaque, mclk() + delta);
#endif
}
(GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t delta)
{
#if ENABLE_GTIMER_CHECK
- GTIMER_FCN(gtimer_arm_absn)(id, fcn, gti, callback, opaque, gdispatch_clock + delta);
+ GTIMER_FCN(gtimer_arm_absn)(id, fcn, gti, callback, opaque, gclk() + delta);
#else
- gtimer_arm_absn(gti, callback, opaque, gdispatch_clock + delta);
+ gtimer_arm_absn(gti, callback, opaque, gclk() + delta);
#endif
}
/**
*
*/
-int64_t
+static int64_t
mdispatch_clock_update(void)
{
int64_t mono = getmonoclock();
- if (mono > mtimer_periodic) {
- mtimer_periodic = mono + MONOCLOCK_RESOLUTION;
+ if (mono > atomic_add_s64(&mtimer_periodic, 0)) {
+ atomic_exchange_s64(&mtimer_periodic, mono + MONOCLOCK_RESOLUTION);
comet_flush(); /* Flush idle comet mailboxes */
}
- return mdispatch_clock = mono;
+ atomic_exchange_s64(&__mdispatch_clock, mono);
+ return mono;
}
/**
{
while (tvheadend_running) {
/* update clocks each 10x in one second */
- mdispatch_clock = getmonoclock();
+ atomic_exchange_s64(&__mdispatch_clock, getmonoclock());
tvh_safe_usleep(100000);
}
return NULL;
/**
*
*/
-time_t
+static inline time_t
gdispatch_clock_update(void)
{
- return gdispatch_clock = time(NULL);
+ time_t now = time(NULL);
+ atomic_exchange_time_t(&__gdispatch_clock, now);
+ return now;
}
/**
tvheadend_webroot = NULL;
tvheadend_htsp_port = 9982;
tvheadend_htsp_port_extra = 0;
- mdispatch_clock = getmonoclock();
- time(&gdispatch_clock);
+ __mdispatch_clock = getmonoclock();
+ __gdispatch_clock = time(NULL);
/* Command line options */
int opt_help = 0,
/* Initialise clock */
pthread_mutex_lock(&global_lock);
- mdispatch_clock = getmonoclock();
- time(&gdispatch_clock);
+ __mdispatch_clock = getmonoclock();
+ __gdispatch_clock = time(NULL);
/* Signal handling */
sigfillset(&set);
if(mk->cluster != NULL)
mk_write_master(mk, 0x1f43b675, mk->cluster);
mk->cluster = NULL;
- mk->cluster_last_close = mdispatch_clock;
+ mk->cluster_last_close = mclk();
}
if(vkeyframe && mk->cluster &&
(mk->cluster->hq_size > mk->cluster_maxsize ||
- mk->cluster_last_close + sec2mono(1) < mdispatch_clock))
+ mk->cluster_last_close + sec2mono(1) < mclk()))
mk_close_cluster(mk);
else if(!mk->has_video && mk->cluster &&
(mk->cluster->hq_size > clusersizemax/40 ||
- mk->cluster_last_close + sec2mono(1) < mdispatch_clock))
+ mk->cluster_last_close + sec2mono(1) < mclk()))
mk_close_cluster(mk);
else if(mk->cluster && mk->cluster->hq_size > clusersizemax)
if ((p = st->es_priv) == NULL) {
p = st->es_priv = calloc(1, sizeof(h264_private_t));
- p->start = mdispatch_clock;
+ p->start = mclk();
}
profile_idc = read_bits(bs, 8);
if((p = st->es_priv) == NULL) {
p = st->es_priv = calloc(1, sizeof(h264_private_t));
- p->start = mdispatch_clock;
+ p->start = mclk();
}
pps_id = read_golomb_ue(bs);
d = 0;
if (sps->time_scale)
d = 180000 * (uint64_t)sps->units_in_tick / (uint64_t)sps->time_scale;
- if (d == 0 && st->es_frame_duration < 2 && p->start + sec2mono(4) < mdispatch_clock) {
+ if (d == 0 && st->es_frame_duration < 2 && p->start + sec2mono(4) < mclk()) {
tvhwarn("parser", "H264 stream has not timing information, using 30fps");
d = 3000; /* 90000/30 = 3000 : 30fps */
}
int i;
struct tm tm;
- t = gdispatch_clock;
+ t = gclk();
localtime_r(&t, &tm);
tm.tm_hour = atoi((char *)buf);
streaming_msg_free(sm);
int64_t diff, diff2, threshold;
- if(tfs == NULL || mdispatch_clock < tf->tf_start_time) {
+ if(tfs == NULL || mclk() < tf->tf_start_time) {
pkt_ref_dec(pkt);
return;
}
TAILQ_INIT(&tf->tf_ptsq);
tf->tf_output = output;
- tf->tf_start_time = mdispatch_clock;
+ tf->tf_start_time = mclk();
streaming_target_init(&tf->tf_input, tsfix_input, tf, 0);
return &tf->tf_input;
satip_rtp_header(satip_rtp_session_t *rtp, struct iovec *v, uint32_t off)
{
uint8_t *data = v->iov_base;
- uint32_t tstamp = mono2sec(mdispatch_clock) + rtp->seq;
+ uint32_t tstamp = mono2sec(mclk()) + rtp->seq;
rtp->seq++;
static void
rtsp_describe_header(session_t *rs, htsbuf_queue_t *q)
{
- unsigned long mono = mdispatch_clock;
+ unsigned long mono = mclk();
int dvbt, dvbc;
htsbuf_append_str(q, "v=0\r\n");
t->s_streaming_live = 0;
t->s_scrambled_seen = 0;
t->s_scrambled_pass = !!(flags & SUBSCRIPTION_NODESCR);
- t->s_start_time = mdispatch_clock;
+ t->s_start_time = mclk();
pthread_mutex_lock(&t->s_stream_mutex);
service_build_filter(t);
/* forced kill for expired PIDs */
pthread_mutex_lock(&spawn_mutex);
LIST_FOREACH(s, &spawns, link)
- if (s->killed && s->killed < mdispatch_clock) {
+ if (s->killed && s->killed < mclk()) {
/* kill the whole process group */
kill(-(s->pid), SIGKILL);
}
break;
if (s) {
if (!s->killed)
- s->killed = mdispatch_clock_update() + sec2mono(MINMAX(timeout, 5, 3600));
+ s->killed = mclk() + sec2mono(MINMAX(timeout, 5, 3600));
/* kill the whole process group */
r = kill(-pid, sig);
if (r < 0)
s->ths_source, s->ths_prch,
&s->ths_instances, error, s->ths_weight,
s->ths_flags, s->ths_timeout,
- mdispatch_clock > s->ths_postpone_end ?
- 0 : mono2sec(s->ths_postpone_end - mdispatch_clock));
+ mclk() > s->ths_postpone_end ?
+ 0 : mono2sec(s->ths_postpone_end - mclk()));
return s->ths_current_instance = si;
}
/* Postpone the tuner decision */
/* Leave some time to wakeup tuners through DBus or so */
- if (s->ths_postpone_end > mdispatch_clock) {
- postpone2 = mono2sec(s->ths_postpone_end - mdispatch_clock);
+ if (s->ths_postpone_end > mclk()) {
+ postpone2 = mono2sec(s->ths_postpone_end - mclk());
if (postpone > postpone2)
postpone = postpone2;
sm = streaming_msg_create_code(SMT_GRACE, postpone + 5);
s->ths_current_instance = si;
if(si == NULL) {
- if (s->ths_last_error != error || s->ths_last_find + sec2mono(2) >= mdispatch_clock) {
+ if (s->ths_last_error != error || s->ths_last_find + sec2mono(2) >= mclk()) {
tvhtrace("subscription", "%04X: instance not available, retrying", shortid(s));
if (s->ths_last_error != error)
- s->ths_last_find = mdispatch_clock;
+ s->ths_last_find = mclk();
s->ths_last_error = error;
continue;
}
subscription_set_postpone(void *aux, const char *path, int64_t postpone)
{
th_subscription_t *s;
- time_t now = mdispatch_clock_update();
+ int64_t now = mclk();
int64_t postpone2;
if (strcmp(path, "/set"))
mtimer_arm_rel(&subscription_reschedule_timer,
subscription_reschedule_cb, NULL, 0);
}
- pthread_mutex_unlock(&global_lock);
+ pthread_mutex_unlock(&global_lock);
return postpone;
}
s->ths_flags = flags;
s->ths_timeout = pro ? pro->pro_timeout : 0;
s->ths_postpone = subscription_postpone;
- s->ths_postpone_end = mdispatch_clock + sec2mono(s->ths_postpone);
+ s->ths_postpone_end = mclk() + sec2mono(s->ths_postpone);
if (s->ths_prch)
s->ths_weight = profile_chain_weight(s->ths_prch, weight);
{
tcp_server_launch_t *tsl, *res;
uint32_t used = 0, used2;
- int64_t started = mdispatch_clock;
+ int64_t started = mclk();
int c1, c2;
lock_assert(&global_lock);
c2 = aa->aa_conn_limit_streaming ? used >= aa->aa_conn_limit_streaming : -1;
if (c1 && c2) {
- if (started + sec2mono(3) < mdispatch_clock) {
+ if (started + sec2mono(3) < mclk()) {
tvherror("tcp", "multiple connections are not allowed for user '%s' from '%s' "
"(limit %u, streaming limit %u, active streaming %u, DVR %u)",
aa->aa_username ?: "", aa->aa_representative ?: "",
tvh_pipe_close(&tcp_server_pipe);
tvhpoll_destroy(tcp_server_poll);
- t = mdispatch_clock;
+ t = mclk();
while (LIST_FIRST(&tcp_server_active) != NULL) {
- if (t + sec2mono(5) < mdispatch_clock)
+ if (t + sec2mono(5) < mclk())
tvhtrace("tcp", "tcp server %p active too long", LIST_FIRST(&tcp_server_active));
tvh_safe_usleep(20000);
}
#include "libav.h"
#include "webui/webui.h"
-int64_t mdispatch_clock;
-time_t gdispatch_clock;
-
int tvhlog_run;
int tvhlog_level;
int tvhlog_options;
static inline void tvhlog_limit_reset ( tvhlog_limit_t *limit )
{ limit->last = 0; limit->count = 0; }
static inline int tvhlog_limit ( tvhlog_limit_t *limit, uint32_t delay )
- { int64_t t = mdispatch_clock; limit->count++;
- if (limit->last + (int64_t)delay * MONOCLOCK_RESOLUTION < t)
- { limit->last = t; return 1; }
+ { int64_t t = mclk(); limit->count++;
+ if (limit->last + sec2mono(delay) < t) { limit->last = t; return 1; }
return 0; }
for(cmb = LIST_FIRST(&mailboxes); cmb != NULL; cmb = next) {
next = LIST_NEXT(cmb, cmb_link);
- if(cmb->cmb_last_used && cmb->cmb_last_used + sec2mono(60) < mdispatch_clock)
+ if(cmb->cmb_last_used && cmb->cmb_last_used + sec2mono(60) < mclk())
cmb_destroy(cmb);
}
pthread_mutex_unlock(&comet_mutex);
cmb->cmb_boxid = strdup(id);
cmb->cmb_lang = lang ? strdup(lang) : NULL;
- cmb->cmb_last_used = mdispatch_clock;
+ cmb->cmb_last_used = mclk();
mailbox_tally++;
LIST_INSERT_HEAD(&mailboxes, cmb, cmb_link);
cmb->cmb_last_used = 0; /* Make sure we're not flushed out */
if(!im && cmb->cmb_messages == NULL) {
- mono = mdispatch_clock + sec2mono(10);
+ mono = mclk() + sec2mono(10);
do {
e = tvh_cond_timedwait(&comet_cond, &comet_mutex, mono);
if (e == ETIMEDOUT)
htsmsg_add_msg(m, "messages", cmb->cmb_messages ?: htsmsg_create_list());
cmb->cmb_messages = NULL;
- cmb->cmb_last_used = mdispatch_clock;
+ cmb->cmb_last_used = mclk();
pthread_mutex_unlock(&comet_mutex);
if (config.dscp >= 0)
socket_set_dscp(hc->hc_fd, config.dscp, NULL, 0);
- lastpkt = mdispatch_clock;
+ lastpkt = mclk();
ptimeout = prch->prch_pro ? prch->prch_pro->pro_timeout : 5;
if (hc->hc_no_output) {
pthread_mutex_lock(&sq->sq_mutex);
sm = TAILQ_FIRST(&sq->sq_queue);
if(sm == NULL) {
- mono = mdispatch_clock + sec2mono(1);
+ mono = mclk() + sec2mono(1);
do {
r = tvh_cond_timedwait(&sq->sq_cond, &sq->sq_mutex, mono);
if (r == ETIMEDOUT) {
if (tcp_socket_dead(hc->hc_fd)) {
tvhlog(LOG_DEBUG, "webui", "Stop streaming %s, client hung up", hc->hc_url_orig);
run = 0;
- } else if((!started && mdispatch_clock - lastpkt > sec2mono(grace)) ||
- (started && ptimeout > 0 && mdispatch_clock - lastpkt > sec2mono(ptimeout))) {
+ } else if((!started && mclk() - lastpkt > sec2mono(grace)) ||
+ (started && ptimeout > 0 && mclk() - lastpkt > sec2mono(ptimeout))) {
tvhlog(LOG_WARNING, "webui", "Stop streaming %s, timeout waiting for packets", hc->hc_url_orig);
run = 0;
}
pb = sm->sm_data;
subscription_add_bytes_out(s, len = pktbuf_len(pb));
if (len > 0)
- lastpkt = mdispatch_clock;
+ lastpkt = mclk();
muxer_write_pkt(mux, sm->sm_type, sm->sm_data);
sm->sm_data = NULL;
}
if (hc->hc_no_output) {
streaming_msg_free(sm);
- mono = mdispatch_clock + sec2mono(2);
- while (mdispatch_clock < mono) {
+ mono = mclk() + sec2mono(2);
+ while (mclk() < mono) {
if (tcp_socket_dead(hc->hc_fd))
break;
tvh_safe_usleep(50000);
tvhlog(LOG_DEBUG, "webui", "Stop streaming %s, client hung up",
hc->hc_url_orig);
run = 0;
- } else if((!started && mdispatch_clock - lastpkt > sec2mono(grace)) ||
- (started && ptimeout > 0 && mdispatch_clock - lastpkt > sec2mono(ptimeout))) {
+ } else if((!started && mclk() - lastpkt > sec2mono(grace)) ||
+ (started && ptimeout > 0 && mclk() - lastpkt > sec2mono(ptimeout))) {
tvhlog(LOG_WARNING, "webui", "Stop streaming %s, timeout waiting for packets", hc->hc_url_orig);
run = 0;
}
int
tvh_write(int fd, const void *buf, size_t len)
{
- int64_t limit = mdispatch_clock + sec2mono(25);
+ int64_t limit = mclk() + sec2mono(25);
ssize_t c;
while (len) {
c = write(fd, buf, len);
if (c < 0) {
if (ERRNO_AGAIN(errno)) {
- if (mdispatch_clock > limit)
+ if (mclk() > limit)
break;
tvh_safe_usleep(100);
continue;