From: Jaroslav Kysela Date: Fri, 4 Mar 2016 17:56:37 +0000 (+0100) Subject: rewrite timers, remove avgstat X-Git-Tag: v4.2.1~964 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a6a23e100967e35618424a8125d2d85abb6ea72c;p=thirdparty%2Ftvheadend.git rewrite timers, remove avgstat --- diff --git a/Makefile b/Makefile index 17f48230f..07e2f17f3 100644 --- a/Makefile +++ b/Makefile @@ -189,7 +189,6 @@ SRCS-1 = \ src/settings.c \ src/htsbuf.c \ src/trap.c \ - src/avg.c \ src/htsstr.c \ src/tvhpoll.c \ src/huffman.c \ diff --git a/src/access.c b/src/access.c index 2c4a09cfa..305bf97f8 100644 --- a/src/access.c +++ b/src/access.c @@ -130,7 +130,7 @@ access_ticket_create(const char *resource, access_t *a) at->at_access = access_copy(a); TAILQ_INSERT_TAIL(&access_tickets, at, at_link); - gtimer_arm(&at->at_timer, access_ticket_timout, at, 60*5); + mtimer_arm_rel(&at->at_timer, access_ticket_timout, at, 60*5); return at->at_id; } @@ -146,7 +146,7 @@ access_ticket_delete(const char *id) if((at = access_ticket_find(id)) == NULL) return -1; - gtimer_disarm(&at->at_timer); + mtimer_disarm(&at->at_timer); access_ticket_destroy(at); return 0; diff --git a/src/access.h b/src/access.h index 61cee6845..5bd7dc17d 100644 --- a/src/access.h +++ b/src/access.h @@ -170,7 +170,7 @@ typedef struct access_ticket { TAILQ_ENTRY(access_ticket) at_link; - gtimer_t at_timer; + mtimer_t at_timer; char *at_resource; access_t *at_access; } access_ticket_t; diff --git a/src/avg.c b/src/avg.c deleted file mode 100644 index 60bdd1b84..000000000 --- a/src/avg.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Averaging functions - * Copyright (C) 2007 Andreas Öman - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "avg.h" -#include - -void -avgstat_init(avgstat_t *as, int depth) -{ - TAILQ_INIT(&as->as_queue); - pthread_mutex_init(&as->as_mutex, NULL); - as->as_depth = depth; -} - - -void -avgstat_flush(avgstat_t *as) -{ - avgstat_entry_t *ase; - - while((ase = TAILQ_FIRST(&as->as_queue)) != NULL) { - TAILQ_REMOVE(&as->as_queue, ase, ase_link); - free(ase); - } -} - - -static void -avgstat_expire(avgstat_t *as, int now) -{ - avgstat_entry_t *ase; - - while(1) { - ase = TAILQ_LAST(&as->as_queue, avgstat_entry_queue); - if(ase == NULL || ase->ase_clock > now - as->as_depth) - break; - TAILQ_REMOVE(&as->as_queue, ase, ase_link); - free(ase); - } -} - - -void -avgstat_add(avgstat_t *as, int count, time_t now) -{ - avgstat_entry_t *ase; - - pthread_mutex_lock(&as->as_mutex); - ase = TAILQ_FIRST(&as->as_queue); - if(ase != NULL && ase->ase_clock == now) { - ase->ase_count += count; - } else { - ase = malloc(sizeof(avgstat_entry_t)); - TAILQ_INSERT_HEAD(&as->as_queue, ase, ase_link); - ase->ase_clock = now; - ase->ase_count = count; - } - - avgstat_expire(as, now); - pthread_mutex_unlock(&as->as_mutex); -} - - -unsigned int -avgstat_read_and_expire(avgstat_t *as, time_t now) -{ - avgstat_entry_t *ase; - int r = 0; - - pthread_mutex_lock(&as->as_mutex); - - avgstat_expire(as, now); - - TAILQ_FOREACH(ase, &as->as_queue, ase_link) - r += ase->ase_count; - - pthread_mutex_unlock(&as->as_mutex); - return r; -} - -unsigned int -avgstat_read(avgstat_t *as, int depth, time_t now) -{ - avgstat_entry_t *ase; - int r = 0; - - pthread_mutex_lock(&as->as_mutex); - - TAILQ_FOREACH(ase, &as->as_queue, ase_link) { - if(ase->ase_clock < now - depth) - break; - r += ase->ase_count; - } - pthread_mutex_unlock(&as->as_mutex); - return r; -} - diff --git a/src/avg.h b/src/avg.h deleted file mode 100644 index d444b2fd1..000000000 --- a/src/avg.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Averaging functions - * Copyright (C) 2007 Andreas Öman - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef AVG_H -#define AVG_H - -#include -#include "queue.h" - -/* - * avg stat queue - */ - -TAILQ_HEAD(avgstat_entry_queue, avgstat_entry); - -typedef struct avgstat { - pthread_mutex_t as_mutex; - struct avgstat_entry_queue as_queue; - int as_depth; /* in seconds */ -} avgstat_t; - -typedef struct avgstat_entry { - TAILQ_ENTRY(avgstat_entry) ase_link; - int ase_clock; - int ase_count; -} avgstat_entry_t; - -void avgstat_init(avgstat_t *as, int maxdepth); -void avgstat_add(avgstat_t *as, int count, time_t now); -void avgstat_flush(avgstat_t *as); -unsigned int avgstat_read_and_expire(avgstat_t *as, time_t now); -unsigned int avgstat_read(avgstat_t *as, int depth, time_t now); - -#endif /* AVG_H */ diff --git a/src/bouquet.c b/src/bouquet.c index 5741a5c43..50749a2b3 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -28,7 +28,7 @@ typedef struct bouquet_download { bouquet_t *bq; download_t download; - gtimer_t timer; + mtimer_t timer; } bouquet_download_t; bouquet_tree_t bouquets; @@ -1029,8 +1029,8 @@ bouquet_download_trigger0(void *aux) bouquet_t *bq = bqd->bq; download_start(&bqd->download, bq->bq_ext_url, bqd); - gtimer_arm(&bqd->timer, bouquet_download_trigger0, bqd, - MAX(1, bq->bq_ext_url_period) * 60); + mtimer_arm_rel(&bqd->timer, bouquet_download_trigger0, bqd, + mono4sec(MAX(1, bq->bq_ext_url_period) * 60)); } static void @@ -1047,7 +1047,7 @@ static void bouquet_download_stop(void *aux) { bouquet_download_t *bqd = aux; - gtimer_disarm(&bqd->timer); + mtimer_disarm(&bqd->timer); } static int diff --git a/src/clock.h b/src/clock.h new file mode 100644 index 000000000..849c9e842 --- /dev/null +++ b/src/clock.h @@ -0,0 +1,108 @@ +/* + * Tvheadend - structures + * Copyright (C) 2007 Andreas Öman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef TVHEADEND_CLOCK_H +#define TVHEADEND_CLOCK_H + +#include + +#ifndef CLOCK_MONOTONIC_COARSE +#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC +#endif + +#ifdef PLATFORM_DARWIN +#define CLOCK_MONOTONIC 0 +#define CLOCK_REALTIME 0 + +static inline int clock_gettime(int clk_id, struct timespec* t) { + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) return rv; + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; +} +#endif + +extern int64_t mdispatch_clock; +extern time_t gdispatch_clock; + +#define MONOCLOCK_RESOLUTION 1000000LL /* microseconds */ + +static inline int64_t +mono4sec(int64_t sec) +{ + return sec * MONOCLOCK_RESOLUTION; +} + +static inline int64_t +sec4mono(int64_t monosec) +{ + return monosec / MONOCLOCK_RESOLUTION; +} + +static inline int64_t +mono4ms(int64_t ms) +{ + return ms * (MONOCLOCK_RESOLUTION / 1000LL); +} + +static inline int64_t +ms4mono(int64_t monosec) +{ + return monosec / (MONOCLOCK_RESOLUTION / 1000LL); +} + +static inline int64_t +getmonoclock(void) +{ + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC, &tp); + + return tp.tv_sec * MONOCLOCK_RESOLUTION + + (tp.tv_nsec / (1000000000LL/MONOCLOCK_RESOLUTION)); +} + +static inline int64_t +getfastmonoclock(void) +{ + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &tp); + + return tp.tv_sec * MONOCLOCK_RESOLUTION + + (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) +{ + time_t r = val; + if ((int64_t)r != val) { + time_t_out_of_range_notify(val); + r = INT32_MAX; + } + return r; +} + +#endif /* TVHEADEND_CLOCK_H */ diff --git a/src/descrambler.h b/src/descrambler.h index cced7f82b..42023e109 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -72,12 +72,12 @@ typedef struct th_descrambler_runtime { uint8_t dr_key_index; uint8_t dr_key_valid; uint8_t dr_key_changed; - uint32_t dr_key_interval; - time_t dr_key_start; - time_t dr_key_timestamp[2]; - time_t dr_ecm_start[2]; - time_t dr_ecm_last_key_time; - time_t dr_last_err; + uint64_t dr_key_interval; + int64_t dr_key_start; + int64_t dr_key_timestamp[2]; + int64_t dr_ecm_start[2]; + int64_t dr_ecm_last_key_time; + int64_t dr_last_err; TAILQ_HEAD(, th_descrambler_data) dr_queue; uint32_t dr_queue_total; tvhlog_limit_t dr_loglimit_key; diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 9cc694253..490f04032 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -1642,6 +1642,7 @@ capmt_thread(void *aux) capmt_adapter_t *ca; capmt_opaque_t *t; int d, i, j, fatal; + int64_t mono; tvhlog(LOG_INFO, "capmt", "%s active", capmt_name(capmt)); @@ -1771,8 +1772,12 @@ capmt_thread(void *aux) tvhlog(LOG_INFO, "capmt", "%s: Automatic reconnection attempt in in %d seconds", idnode_get_title(&capmt->cac_id, NULL), d); - tvh_cond_timedwait(&capmt->capmt_cond, &capmt->capmt_mutex, - getmonoclock() + d * MONOCLOCK_RESOLUTION); + mono = mdispatch_clock + mono4sec(d); + do { + i = tvh_cond_timedwait(&capmt->capmt_cond, &capmt->capmt_mutex, mono); + if (i == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(i)); pthread_mutex_unlock(&capmt->capmt_mutex); } diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 9f15631f4..a39510757 100644 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -711,7 +711,7 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg, char chaninfo[128]; int i; uint32_t off; - int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms + int64_t delay = (getfastmonoclock() - es->es_time) / 1000LL; // in ms es->es_pending = 0; @@ -1046,6 +1046,7 @@ cwc_writer_thread(void *aux) { cwc_t *cwc = aux; cwc_message_t *cm; + int64_t mono; int r; pthread_mutex_lock(&cwc->cwc_writer_mutex); @@ -1055,10 +1056,10 @@ cwc_writer_thread(void *aux) if((cm = TAILQ_FIRST(&cwc->cwc_writeq)) != NULL) { TAILQ_REMOVE(&cwc->cwc_writeq, cm, cm_link); pthread_mutex_unlock(&cwc->cwc_writer_mutex); - // int64_t ts = getmonoclock(); + // int64_t ts = getfastmonoclock(); if (tvh_write(cwc->cwc_fd, cm->cm_data, cm->cm_len)) tvhlog(LOG_INFO, "cwc", "write error %s", strerror(errno)); - // printf("Write took %lld usec\n", getmonoclock() - ts); + // printf("Write took %lld usec\n", getfastmonoclock() - ts); free(cm); pthread_mutex_lock(&cwc->cwc_writer_mutex); continue; @@ -1067,11 +1068,14 @@ cwc_writer_thread(void *aux) /* If nothing is to be sent in CWC_KEEPALIVE_INTERVAL seconds we need to send a keepalive */ - r = tvh_cond_timedwait(&cwc->cwc_writer_cond, - &cwc->cwc_writer_mutex, - getmonoclock() + CWC_KEEPALIVE_INTERVAL * MONOCLOCK_RESOLUTION); - if(r == ETIMEDOUT) - cwc_send_ka(cwc); + mono = mdispatch_clock + mono4sec(CWC_KEEPALIVE_INTERVAL); + do { + r = tvh_cond_timedwait(&cwc->cwc_writer_cond, &cwc->cwc_writer_mutex, mono); + if(r == ETIMEDOUT) { + cwc_send_ka(cwc); + break; + } + } while (ERRNO_AGAIN(r)); } pthread_mutex_unlock(&cwc->cwc_writer_mutex); @@ -1178,11 +1182,12 @@ static void * cwc_thread(void *aux) { cwc_t *cwc = aux; - int fd, d; + int fd, d, r; char errbuf[100]; char hostname[256]; int port; int attempts = 0; + int64_t mono; pthread_mutex_lock(&cwc->cwc_mutex); @@ -1242,8 +1247,12 @@ cwc_thread(void *aux) "%s:%i: Automatic connection attempt in %d seconds", cwc->cwc_hostname, cwc->cwc_port, d-1); - tvh_cond_timedwait(&cwc->cwc_cond, &cwc->cwc_mutex, - getmonoclock() + d * MONOCLOCK_RESOLUTION); + mono = mdispatch_clock + mono4sec(d); + do { + r = tvh_cond_timedwait(&cwc->cwc_cond, &cwc->cwc_mutex, mono); + if (r == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(r)); } tvhlog(LOG_INFO, "cwc", "%s:%i inactive", @@ -1307,11 +1316,10 @@ cwc_emm(void *opaque, int pid, const uint8_t *data, int len, int emm) if (pcard->running && cwc->cwc_forward_emm && cwc->cwc_writer_running) { if (cwc->cwc_emmex) { if (cwc->cwc_mux != mux) { - int64_t delta = getmonoclock() - cwc->cwc_update_time; - if (delta < 25000000UL) /* 25 seconds */ + if (cwc->cwc_update_time + mono4sec(25) < mdispatch_clock) goto end_of_job; } - cwc->cwc_update_time = getmonoclock(); + cwc->cwc_update_time = mdispatch_clock; } cwc->cwc_mux = mux; emm_filter(&pcard->cs_ra, data, len, mux, cwc_emm_send, pcard); @@ -1469,7 +1477,7 @@ found: tvhlog(LOG_DEBUG, "cwc", "Sending ECM%s section=%d/%d, for service \"%s\" (seqno: %d)", chaninfo, section, ep->ep_last_section, t->s_dvb_svcname, es->es_seq); - es->es_time = getmonoclock(); + es->es_time = getfastmonoclock(); break; default: diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index cc9d0a9bd..a6968a69a 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -35,7 +35,7 @@ typedef struct th_descrambler_data { TAILQ_ENTRY(th_descrambler_data) dd_link; - time_t dd_timestamp; + int64_t dd_timestamp; sbuf_t dd_sbuf; } th_descrambler_data_t; @@ -66,7 +66,7 @@ descrambler_data_destroy(th_descrambler_runtime_t *dr, th_descrambler_data_t *dd } static void -descrambler_data_time_flush(th_descrambler_runtime_t *dr, time_t oldest) +descrambler_data_time_flush(th_descrambler_runtime_t *dr, int64_t oldest) { th_descrambler_data_t *dd; @@ -84,14 +84,14 @@ descrambler_data_append(th_descrambler_runtime_t *dr, const uint8_t *tsb, int le if (len == 0) return; dd = TAILQ_LAST(&dr->dr_queue, th_descrambler_queue); - if (dd && dd->dd_timestamp == dispatch_clock && + if (dd && sec4mono(dd->dd_timestamp) == sec4mono(mdispatch_clock) && (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 = dispatch_clock; + dd->dd_timestamp = mdispatch_clock; sbuf_init(&dd->dd_sbuf); sbuf_append(&dd->dd_sbuf, tsb, len); TAILQ_INSERT_TAIL(&dr->dr_queue, dd, dd_link); @@ -276,7 +276,7 @@ descrambler_service_start ( service_t *t ) dr->dr_service = t; TAILQ_INIT(&dr->dr_queue); dr->dr_key_index = 0xff; - dr->dr_key_interval = 10; + dr->dr_key_interval = mono4sec(10); dr->dr_key_const = constcw; if (constcw) tvhtrace("descrambler", "using constcw for \"%s\"", t->s_nicename); @@ -451,14 +451,14 @@ descrambler_keys ( th_descrambler_t *td, int type, 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] = dispatch_clock; + dr->dr_key_timestamp[0] = mdispatch_clock; } 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] = dispatch_clock; + dr->dr_key_timestamp[1] = mdispatch_clock; } if (j) { @@ -491,7 +491,7 @@ descrambler_keys ( th_descrambler_t *td, int type, 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 = dispatch_clock; + dr->dr_ecm_last_key_time = mdispatch_clock; td->td_keystate = DS_RESOLVED; td->td_service->s_descrambler = td; } else { @@ -569,25 +569,25 @@ descrambler_flush_table_data( service_t *t ) } static inline void -key_update( th_descrambler_runtime_t *dr, uint8_t key, time_t timestamp ) +key_update( th_descrambler_runtime_t *dr, uint8_t key, int64_t timestamp ) { /* set the even (0) or odd (0x40) key index */ dr->dr_key_index = key & 0x40; if (dr->dr_key_start) { - dr->dr_key_interval = dr->dr_key_start + 50 < timestamp ? - 10 : timestamp - dr->dr_key_start; + dr->dr_key_interval = dr->dr_key_start + mono4sec(50) < timestamp ? + mono4sec(10) : timestamp - dr->dr_key_start; dr->dr_key_start = timestamp; } else { /* We don't know the exact start key switch time */ - dr->dr_key_start = timestamp - 60; + dr->dr_key_start = timestamp - mono4sec(60); } } static inline int -key_changed ( th_descrambler_runtime_t *dr, uint8_t ki, time_t timestamp ) +key_changed ( th_descrambler_runtime_t *dr, uint8_t ki, int64_t timestamp ) { return dr->dr_key_index != (ki & 0x40) && - dr->dr_key_start + 2 < timestamp; + dr->dr_key_start + mono4sec(2) < timestamp; } static inline int @@ -599,7 +599,7 @@ key_valid ( th_descrambler_runtime_t *dr, uint8_t ki ) } static inline int -key_late( th_descrambler_runtime_t *dr, uint8_t ki, time_t timestamp ) +key_late( th_descrambler_runtime_t *dr, uint8_t ki, int64_t timestamp ) { uint8_t kidx = (ki & 0x40) >> 6; /* constcw - do not handle keys */ @@ -612,7 +612,7 @@ key_late( th_descrambler_runtime_t *dr, uint8_t ki, time_t timestamp ) goto late; } /* ECM was sent, but no new key was received */ - if (dr->dr_ecm_last_key_time + 2 < dr->dr_key_start && + if (dr->dr_ecm_last_key_time + mono4sec(2) < dr->dr_key_start && (!dr->dr_quick_ecm || dr->dr_ecm_start[kidx] + 4 < dr->dr_key_start)) { late: dr->dr_key_valid &= ~((ki & 0x40) + 0x40); @@ -625,7 +625,7 @@ static inline int key_started( th_descrambler_runtime_t *dr, uint8_t ki ) { uint8_t kidx = (ki & 0x40) >> 6; - return (int64_t)dispatch_clock - (int64_t)dr->dr_ecm_start[kidx] < 5; + return mdispatch_clock - dr->dr_ecm_start[kidx] < mono4sec(5); } static int @@ -699,7 +699,7 @@ descrambler_descramble ( service_t *t, /* process the queued TS packets */ if (dr->dr_queue_total > 0) { - descrambler_data_time_flush(dr, dispatch_clock - (dr->dr_key_interval - 2)); + descrambler_data_time_flush(dr, mdispatch_clock - (dr->dr_key_interval - mono4sec(2))); for (dd = TAILQ_FIRST(&dr->dr_queue); dd; dd = dd_next) { dd_next = TAILQ_NEXT(dd, dd_link); sb = &dd->dd_sbuf; @@ -745,13 +745,13 @@ descrambler_descramble ( service_t *t, "even stream key is not valid"); goto next; } - if (key_changed(dr, ki, dispatch_clock)) { + if (key_changed(dr, ki, mdispatch_clock)) { 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, dispatch_clock)) { - tvherror("descrambler", "ECM - key late (%ld seconds) for service \"%s\"", - dispatch_clock - dr->dr_ecm_last_key_time, + if (key_late(dr, ki, mdispatch_clock)) { + tvherror("descrambler", "ECM - key late (%ld ms) for service \"%s\"", + ms4mono(mdispatch_clock - dr->dr_ecm_last_key_time), ((mpegts_service_t *)t)->s_dvb_svcname); descrambler_notify_nokey(dr); if (ecm_reset(t, dr)) { @@ -759,7 +759,7 @@ descrambler_descramble ( service_t *t, goto next; } } - key_update(dr, ki, dispatch_clock); + key_update(dr, ki, mdispatch_clock); } } dr->dr_skip = 1; @@ -778,18 +778,18 @@ next: 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, dispatch_clock); + key_update(dr, ki, mdispatch_clock); break; } else { descrambler_data_cut(dr, 188); } } } else if (dr->dr_key_index != (ki & 0x40) && - dr->dr_key_start + 2 < dispatch_clock) { + dr->dr_key_start + mono4sec(2) < mdispatch_clock) { 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, dispatch_clock); + key_update(dr, ki, mdispatch_clock); } } if (count != failed) { @@ -800,8 +800,8 @@ next: 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 + 10 < dispatch_clock) { - dr->dr_last_err = dispatch_clock; + if (dr->dr_last_err + mono4sec(10) < mdispatch_clock) { + dr->dr_last_err = mdispatch_clock; tvherror("descrambler", "cannot decode packets for service \"%s\"", ((mpegts_service_t *)t)->s_dvb_svcname); } else { @@ -873,7 +873,7 @@ descrambler_table_callback t->s_dvb_svcname); } if ((ptr[0] & 0xfe) == 0x80) { /* 0x80 = even, 0x81 = odd */ - dr->dr_ecm_start[ptr[0] & 1] = dispatch_clock; + dr->dr_ecm_start[ptr[0] & 1] = mdispatch_clock; if (dr->dr_quick_ecm) dr->dr_key_valid &= ~(1 << ((ptr[0] & 1) + 6)); /* 0x40 = even, 0x80 = odd */ } diff --git a/src/download.c b/src/download.c index 185714d80..4303656e4 100644 --- a/src/download.c +++ b/src/download.c @@ -126,7 +126,7 @@ download_fetch_complete(http_client_t *hc) hc->hc_code, hc->hc_result, hc->hc_data_size); /* note: http_client_close must be called outside http_client callbacks */ - gtimer_arm(&dn->fetch_timer, download_fetch_done, hc, 0); + mtimer_arm_rel(&dn->fetch_timer, download_fetch_done, hc, 0); out: pthread_mutex_unlock(&global_lock); @@ -193,7 +193,7 @@ failed: } } - gtimer_arm_ms(&dn->pipe_read_timer, download_pipe_read, dn, 250); + mtimer_arm_rel(&dn->pipe_read_timer, download_pipe_read, dn, mono4ms(250)); } /* @@ -206,7 +206,7 @@ download_pipe(download_t *dn, const char *args) int r; download_pipe_close(dn); - gtimer_disarm(&dn->pipe_read_timer); + mtimer_disarm(&dn->pipe_read_timer); /* Arguments */ if (spawn_parse_args(&argv, 64, args, NULL)) { @@ -228,7 +228,7 @@ download_pipe(download_t *dn, const char *args) fcntl(dn->pipe_fd, F_SETFL, fcntl(dn->pipe_fd, F_GETFL) | O_NONBLOCK); - gtimer_arm_ms(&dn->pipe_read_timer, download_pipe_read, dn, 250); + mtimer_arm_rel(&dn->pipe_read_timer, download_pipe_read, dn, mono4ms(250)); return 0; } @@ -319,7 +319,7 @@ download_start( download_t *dn, const char *url, void *aux ) dn->url = strdup(url); } dn->aux = aux; - gtimer_arm(&dn->fetch_timer, download_fetch, dn, 0); + mtimer_arm_rel(&dn->fetch_timer, download_fetch, dn, 0); } /* @@ -333,8 +333,8 @@ download_done( download_t *dn ) dn->http_client = NULL; } download_pipe_close(dn); - gtimer_disarm(&dn->fetch_timer); - gtimer_disarm(&dn->pipe_read_timer); + mtimer_disarm(&dn->fetch_timer); + mtimer_disarm(&dn->pipe_read_timer); free(dn->log); dn->log = NULL; free(dn->url); dn->url = NULL; } diff --git a/src/download.h b/src/download.h index 3322d77b3..9ac7287e5 100644 --- a/src/download.h +++ b/src/download.h @@ -32,8 +32,8 @@ typedef struct download { void (*stop)(void *aux); /* internal members */ http_client_t *http_client; - gtimer_t fetch_timer; - gtimer_t pipe_read_timer; + mtimer_t fetch_timer; + mtimer_t pipe_read_timer; sbuf_t pipe_sbuf; int pipe_fd; pid_t pipe_pid; diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 36c859c03..437375540 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -164,7 +164,7 @@ typedef struct dvr_entry { char *de_channel_name; gtimer_t de_timer; - gtimer_t de_deferred_timer; + mtimer_t de_deferred_timer; /** * These meta fields will stay valid as long as reference count > 0 @@ -269,7 +269,7 @@ typedef struct dvr_entry { /** * Entry change notification timer */ - time_t de_last_notify; + int64_t de_last_notify; /** * Update notification limit diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 1ab28eccc..b00f981ea 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -39,7 +39,7 @@ struct dvr_entry_list dvrentries; static int dvr_in_init; #if ENABLE_DBUS_1 -static gtimer_t dvr_dbus_timer; +static mtimer_t dvr_dbus_timer; #endif static void dvr_entry_deferred_destroy(dvr_entry_t *de); @@ -354,7 +354,7 @@ dvr_dbus_timer_cb( void *aux ) if (de->de_sched_state != DVR_SCHEDULED) continue; start = dvr_entry_get_start_time(de, 1); - if (dispatch_clock < start && start > max) + if (gdispatch_clock < start && start > max) max = start; } /* lower the maximum value */ @@ -363,7 +363,7 @@ dvr_dbus_timer_cb( void *aux ) if (de->de_sched_state != DVR_SCHEDULED) continue; start = dvr_entry_get_start_time(de, 1); - if (dispatch_clock < start && start < result) + if (gdispatch_clock < start && start < result) result = start; } /* different? send it.... */ @@ -381,11 +381,11 @@ static void 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 - dispatch_clock) > 3600) { - when = dispatch_clock + 3600; + if (rerecord && (when - gdispatch_clock) > 3600) { + when = gdispatch_clock + 3600; cb = dvr_timer_rerecord; } - gtimer_arm_abs(&de->de_timer, cb, de, when); + gtimer_arm_absn(&de->de_timer, cb, de, when); } /* @@ -401,7 +401,7 @@ dvr_entry_retention_timer(dvr_entry_t *de) 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 > dispatch_clock) { + if (stop > gdispatch_clock) { dvr_entry_retention_arm(de, dvr_timer_remove_files, stop); return; } @@ -605,7 +605,7 @@ dvr_entry_set_timer(dvr_entry_t *de) /* EPG thinks that the program is running */ if(de->de_running_start > de->de_running_stop && !de->de_dont_reschedule) { - stop = dispatch_clock + 10; + stop = gdispatch_clock + 10; if (de->de_sched_state == DVR_RECORDING) goto recording; } @@ -622,16 +622,16 @@ dvr_entry_set_timer(dvr_entry_t *de) } else if (de->de_sched_state == DVR_RECORDING) { recording: - gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de, stop); + gtimer_arm_absn(&de->de_timer, dvr_timer_stop_recording, de, stop); } else if (de->de_channel && de->de_channel->ch_enabled) { dvr_entry_set_state(de, DVR_SCHEDULED, DVR_RS_PENDING, de->de_last_error); tvhtrace("dvr", "entry timer scheduled for %"PRItime_t, start); - gtimer_arm_abs(&de->de_timer, dvr_timer_start_recording, de, start); + gtimer_arm_absn(&de->de_timer, dvr_timer_start_recording, de, start); #if ENABLE_DBUS_1 - gtimer_arm(&dvr_dbus_timer, dvr_dbus_timer_cb, NULL, 5); + mtimer_arm_rel(&dvr_dbus_timer, dvr_dbus_timer_cb, NULL, mono4sec(5)); #endif } else { @@ -951,7 +951,7 @@ dvr_entry_clone(dvr_entry_t *de) 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 = dispatch_clock; + n->de_start = gdispatch_clock; dvr_entry_start_recording(n, 1); } else { dvr_entry_set_timer(n); @@ -1031,7 +1031,7 @@ not_so_good: 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 < dispatch_clock) continue; + if (ev->start - pre < gdispatch_clock) continue; if (dvr_entry_fuzzy_match(de, ev, 0, INT64_MAX)) if (!e || e->start > ev->start) e = ev; @@ -1347,9 +1347,9 @@ dvr_entry_destroy(dvr_entry_t *de, int delconf) #endif gtimer_disarm(&de->de_timer); - gtimer_disarm(&de->de_deferred_timer); + mtimer_disarm(&de->de_deferred_timer); #if ENABLE_DBUS_1 - gtimer_arm(&dvr_dbus_timer, dvr_dbus_timer_cb, NULL, 2); + mtimer_arm_rel(&dvr_dbus_timer, dvr_dbus_timer_cb, NULL, mono4sec(2)); #endif if (de->de_channel) @@ -1376,7 +1376,7 @@ static void _deferred_destroy_cb(void *aux) static void dvr_entry_deferred_destroy(dvr_entry_t *de) { - gtimer_arm(&de->de_deferred_timer, _deferred_destroy_cb, de, 0); + mtimer_arm_rel(&de->de_deferred_timer, _deferred_destroy_cb, de, 0); } /** @@ -1497,8 +1497,8 @@ static dvr_entry_t *_dvr_entry_update if (!dvr_entry_is_editable(de)) { if (stop > 0) { - if (stop < dispatch_clock) - stop = dispatch_clock; + if (stop < gdispatch_clock) + stop = gdispatch_clock; if (stop < de->de_start) stop = de->de_start; if (stop != de->de_stop) { @@ -1813,10 +1813,10 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, epg_running_t runn 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, dispatch_clock); + atomic_exchange_time_t(&de->de_running_start, gdispatch_clock); } - if (dvr_entry_get_start_time(de, 1) > dispatch_clock) { - atomic_exchange_time_t(&de->de_start, dispatch_clock); + if (dvr_entry_get_start_time(de, 1) > gdispatch_clock) { + atomic_exchange_time_t(&de->de_start, gdispatch_clock); dvr_entry_set_timer(de); tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start", idnode_uuid_as_str(&de->de_id, ubuf), @@ -1830,7 +1830,7 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, epg_running_t runn * 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 > dispatch_clock) + if (de->de_running_start + 5 > gdispatch_clock) continue; srcname = de->de_dvb_eid == e->dvb_eid ? "event" : "other running event"; @@ -1841,7 +1841,7 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, epg_running_t runn epg_broadcast_get_title(e, NULL), channel_get_name(de->de_channel)); } - atomic_exchange_time_t(&de->de_running_stop, dispatch_clock); + atomic_exchange_time_t(&de->de_running_stop, gdispatch_clock); 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); @@ -1856,7 +1856,7 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, epg_running_t runn 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, dispatch_clock); + atomic_exchange_time_t(&de->de_running_pause, gdispatch_clock); } } } @@ -1914,7 +1914,7 @@ dvr_timer_stop_recording(void *aux) return; /* EPG thinks that the program is running */ if (de->de_running_start > de->de_running_stop) { - gtimer_arm(&de->de_timer, dvr_timer_stop_recording, de, 10); + gtimer_arm_rel(&de->de_timer, dvr_timer_stop_recording, de, 10); return; } dvr_stop_recording(aux, SM_CODE_OK, 1, 0); @@ -1947,8 +1947,8 @@ dvr_entry_start_recording(dvr_entry_t *de, int clone) return; } - gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de, - dvr_entry_get_stop_time(de)); + gtimer_arm_absn(&de->de_timer, dvr_timer_stop_recording, de, + dvr_entry_get_stop_time(de)); } @@ -2168,8 +2168,8 @@ dvr_entry_class_stop_set(void *o, const void *_v) time_t v = *(time_t *)_v; if (!dvr_entry_is_editable(de)) { - if (v < dispatch_clock) - v = dispatch_clock; + if (v < gdispatch_clock) + v = gdispatch_clock; } if (v < de->de_start) v = de->de_start; diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index b2460dc0d..cea27874f 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -878,9 +878,9 @@ dvr_rec_fatal_error(dvr_entry_t *de, const char *fmt, ...) static void dvr_notify(dvr_entry_t *de) { - if (de->de_last_notify + 5 < dispatch_clock) { + if (de->de_last_notify + mono4sec(5) < mdispatch_clock) { idnode_notify_changed(&de->de_id); - de->de_last_notify = dispatch_clock; + de->de_last_notify = mdispatch_clock; htsp_dvr_entry_update(de); } } @@ -1272,7 +1272,7 @@ dvr_thread(void *aux) streaming_queue_remove(sq, sm); if (running_disabled) { - epg_running = real_start <= dispatch_clock; + epg_running = real_start <= gdispatch_clock; } 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); @@ -1281,13 +1281,13 @@ dvr_thread(void *aux) 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 >= dispatch_clock) { + if (start_time + 2 >= gdispatch_clock) { TAILQ_INSERT_TAIL(&backlog, sm, sm_link); continue; } else { if (TAILQ_FIRST(&backlog)) streaming_queue_clear(&backlog); - epg_running = real_start <= dispatch_clock; + epg_running = real_start <= gdispatch_clock; } } else { epg_running = 0; @@ -1409,7 +1409,7 @@ dvr_thread(void *aux) break; case SMT_START: - start_time = dispatch_clock; + start_time = gdispatch_clock; packets = 0; if (ss) streaming_start_unref(ss); diff --git a/src/dvr/dvr_timerec.c b/src/dvr/dvr_timerec.c index 66a053456..f1ff17883 100644 --- a/src/dvr/dvr_timerec.c +++ b/src/dvr/dvr_timerec.c @@ -36,7 +36,7 @@ struct dvr_timerec_entry_queue timerec_entries; -static gtimer_t dvr_timerec_timer; +static mtimer_t dvr_timerec_timer; /** * @@ -119,15 +119,15 @@ dvr_timerec_check(dvr_timerec_entry_t *dte) if(dte->dte_channel == NULL) goto fail; - limit = dispatch_clock - 600; - start = dvr_timerec_timecorrection(dispatch_clock, dte->dte_start, &tm_start); - stop = dvr_timerec_timecorrection(dispatch_clock, dte->dte_stop, &tm_stop); + 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); if (start < limit && stop < limit) { /* next day */ - start = dvr_timerec_timecorrection(dispatch_clock + 24*60*60, + start = dvr_timerec_timecorrection(gdispatch_clock + 24*60*60, dte->dte_start, &tm_start); - stop = dvr_timerec_timecorrection(dispatch_clock + 24*60*60, + stop = dvr_timerec_timecorrection(gdispatch_clock + 24*60*60, dte->dte_stop, &tm_stop); } @@ -716,7 +716,7 @@ dvr_timerec_timer_cb(void *aux) } /* load the timer */ - gtimer_arm(&dvr_timerec_timer, dvr_timerec_timer_cb, NULL, 3550); + mtimer_arm_rel(&dvr_timerec_timer, dvr_timerec_timer_cb, NULL, mono4sec(3550)); } void diff --git a/src/dvr/dvr_vfsmgr.c b/src/dvr/dvr_vfsmgr.c index afe03f157..bd7e0d45d 100644 --- a/src/dvr/dvr_vfsmgr.c +++ b/src/dvr/dvr_vfsmgr.c @@ -38,12 +38,12 @@ struct dvr_vfs_list dvrvfs_list; static int dvr_disk_space_config_idx; static int dvr_disk_space_config_size; -static time_t dvr_disk_space_config_lastdelete; +static int64_t dvr_disk_space_config_lastdelete; static int64_t dvr_bfree; static int64_t dvr_btotal; static int64_t dvr_bused; static pthread_mutex_t dvr_disk_space_mutex; -static gtimer_t dvr_disk_space_timer; +static mtimer_t dvr_disk_space_timer; static tasklet_t dvr_disk_space_tasklet; /* @@ -204,7 +204,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg) /* 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 + 10 > dispatch_clock) { + if (dvr_disk_space_config_lastdelete + mono4sec(10) > mdispatch_clock) { tvhlog(LOG_WARNING, "dvr","disk space cleanup for config \"%s\" is not allowed now", configName); return -1; } @@ -221,7 +221,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg) while (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { oldest = NULL; - stoptime = dispatch_clock; + stoptime = gdispatch_clock; LIST_FOREACH(de, &dvrentries, de_global_link) { if (de->de_sched_state != DVR_COMPLETED && @@ -261,7 +261,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg) 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 = dispatch_clock; + dvr_disk_space_config_lastdelete = mdispatch_clock; 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 @@ -429,7 +429,7 @@ dvr_get_disk_space_cb(void *aux) path = strdup(cfg->dvr_storage); tasklet_arm(&dvr_disk_space_tasklet, dvr_get_disk_space_tcb, path); } - gtimer_arm(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, 15); + mtimer_arm_rel(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, mono4sec(15)); } /** @@ -450,7 +450,7 @@ dvr_disk_space_init(void) dvr_config_t *cfg = dvr_config_find_by_name_default(NULL); pthread_mutex_init(&dvr_disk_space_mutex, NULL); dvr_get_disk_space_update(cfg->dvr_storage, 1); - gtimer_arm(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, 5); + mtimer_arm_rel(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, mono4sec(5)); } /** @@ -462,7 +462,7 @@ dvr_disk_space_done(void) dvr_vfs_t *vfs; tasklet_disarm(&dvr_disk_space_tasklet); - gtimer_disarm(&dvr_disk_space_timer); + mtimer_disarm(&dvr_disk_space_timer); while ((vfs = LIST_FIRST(&dvrvfs_list)) != NULL) { LIST_REMOVE(vfs, link); free(vfs); diff --git a/src/epg.c b/src/epg.c index de01e7e62..003afdf45 100644 --- a/src/epg.c +++ b/src/epg.c @@ -135,7 +135,7 @@ void epg_updated ( void ) eo->update(eo); LIST_REMOVE(eo, up_link); eo->_updated = 0; - eo->created = dispatch_clock; + eo->_created = 1; } } @@ -181,7 +181,7 @@ static void _epg_object_set_updated ( void *o ) tvhtrace("epg", "eo [%p, %u, %d, %s] updated", eo, eo->id, eo->type, eo->uri); eo->_updated = 1; - eo->updated = dispatch_clock; + eo->updated = gdispatch_clock; LIST_INSERT_HEAD(&epg_object_updated, eo, up_link); } } @@ -1546,7 +1546,7 @@ static void _epg_channel_timer_callback ( void *p ) if ((cur = ch->ch_epg_now)) { if (cur->running != EPG_RUNNING_STOP) { /* running? don't do anything */ - gtimer_arm(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, 2); + gtimer_arm_rel(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, 2); return; } cur->getref(cur); @@ -1559,7 +1559,7 @@ static void _epg_channel_timer_callback ( void *p ) while ((ebc = RB_FIRST(&ch->ch_epg_schedule))) { /* Expire */ - if ( ebc->stop <= dispatch_clock ) { + if ( ebc->stop <= gdispatch_clock ) { tvhlog(LOG_DEBUG, "epg", "expire event %u (%s) from %s", ebc->id, epg_broadcast_get_title(ebc, NULL), channel_get_name(ch)); @@ -1567,7 +1567,7 @@ static void _epg_channel_timer_callback ( void *p ) continue; // skip to next /* No now */ - } else if (ebc->start > dispatch_clock) { + } else if (ebc->start > gdispatch_clock) { ch->ch_epg_next = ebc; next = ebc->start; @@ -1595,7 +1595,7 @@ static void _epg_channel_timer_callback ( void *p ) if (next) { tvhlog(LOG_DEBUG, "epg", "arm channel timer @ %"PRItime_t" for %s", next, channel_get_name(ch)); - gtimer_arm_abs(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, next); + gtimer_arm_absn(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, next); } /* Remove refs */ @@ -1705,7 +1705,7 @@ static void _epg_broadcast_destroy ( void *eo ) epg_broadcast_t *ebc = eo; char id[16]; - if (ebc->created) { + if (ebc->_created) { htsp_event_delete(ebc); snprintf(id, sizeof(id), "%u", ebc->id); notify_delayed(id, "epg", "delete"); @@ -1728,7 +1728,7 @@ static void _epg_broadcast_updated ( void *eo ) else id[0] = '\0'; - if (ebc->created) { + if (ebc->_created) { htsp_event_update(eo); notify_delayed(id, "epg", "update"); } else { @@ -1761,7 +1761,7 @@ epg_broadcast_t *epg_broadcast_find_by_time epg_broadcast_t **ebc; if (!channel || !start || !stop) return NULL; if (stop <= start) return NULL; - if (stop <= dispatch_clock) return NULL; + if (stop <= gdispatch_clock) return NULL; ebc = _epg_broadcast_skel(); (*ebc)->start = start; @@ -1864,7 +1864,7 @@ void epg_broadcast_notify_running now = ch ? ch->ch_epg_now : NULL; if (running == EPG_RUNNING_STOP) { if (now == broadcast && orunning == broadcast->running) - broadcast->stop = dispatch_clock - 1; + broadcast->stop = gdispatch_clock - 1; } else { if (broadcast != now && now) { now->running = EPG_RUNNING_STOP; @@ -2090,7 +2090,7 @@ epg_broadcast_t *epg_broadcast_deserialize if (htsmsg_get_s64(m, "stop", &stop)) return NULL; if (!start || !stop) return NULL; if (stop <= start) return NULL; - if (stop <= dispatch_clock) return NULL; + if (stop <= gdispatch_clock) return NULL; if (!(str = htsmsg_get_str(m, "episode"))) return NULL; _epg_object_deserialize(m, (epg_object_t*)*skel); @@ -2538,7 +2538,7 @@ _eq_add ( epg_query_t *eq, epg_broadcast_t *e ) /* Filtering */ if (e == NULL) return; - if (e->stop < dispatch_clock) return; + if (e->stop < gdispatch_clock) 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) { diff --git a/src/epg.h b/src/epg.h index d720f3f6a..6ecf16eae 100644 --- a/src/epg.h +++ b/src/epg.h @@ -139,10 +139,10 @@ struct epg_object epg_object_type_t type; ///< Specific object type uint32_t id; ///< Internal ID char *uri; ///< Unique ID (from grabber) - time_t created; ///< Time the object was created time_t updated; ///< Last time object was changed - int _updated; ///< Flag to indicate updated + uint8_t _updated; ///< Flag to indicate updated + uint8_t _created; ///< Flag to indicate creation int refcount; ///< Reference counting // Note: could use LIST_ENTRY field to determine this! diff --git a/src/epgdb.c b/src/epgdb.c index 513184c62..111960f24 100644 --- a/src/epgdb.c +++ b/src/epgdb.c @@ -382,8 +382,8 @@ void epg_save ( void ) sbuf_init_fixed(sb, EPG_DB_ALLOC_STEP); if (epggrab_conf.epgdb_periodicsave) - gtimer_arm(&epggrab_save_timer, epg_save_callback, NULL, - epggrab_conf.epgdb_periodicsave * 3600); + gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, + epggrab_conf.epgdb_periodicsave * 3600); memset(&stats, 0, sizeof(stats)); if ( _epg_write_sect(sb, "config") ) goto error; diff --git a/src/epggrab.c b/src/epggrab.c index c8ca9c010..3092640be 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -173,8 +173,8 @@ static void _epggrab_load ( void ) } if (epggrab_conf.epgdb_periodicsave) - gtimer_arm(&epggrab_save_timer, epg_save_callback, NULL, - epggrab_conf.epgdb_periodicsave * 3600); + gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, + epggrab_conf.epgdb_periodicsave * 3600); idnode_notify_changed(&epggrab_conf.idnode); diff --git a/src/epggrab.h b/src/epggrab.h index 73e969588..73e37476a 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -210,8 +210,8 @@ struct epggrab_ota_mux uint8_t om_complete; ///< Has completed a scan uint8_t om_requeue; ///< Requeue when stolen uint8_t om_save; ///< something changed - gtimer_t om_timer; ///< Per mux active timer - gtimer_t om_data_timer; ///< Any EPG data seen? + mtimer_t om_timer; ///< Per mux active timer + mtimer_t om_data_timer; ///< Any EPG data seen? char *om_force_modname;///< Force this module diff --git a/src/epggrab/module/psip.c b/src/epggrab/module/psip.c index 60276af89..32b52a7ea 100644 --- a/src/epggrab/module/psip.c +++ b/src/epggrab/module/psip.c @@ -41,7 +41,7 @@ static int _psip_ett_callback(mpegts_table_t *mt, const uint8_t *ptr, int len, i typedef struct psip_table { TAILQ_ENTRY(psip_table) pt_link; mpegts_table_t *pt_table; - time_t pt_start; + int64_t pt_start; uint16_t pt_pid; uint16_t pt_type; uint8_t pt_complete; @@ -62,7 +62,7 @@ typedef struct psip_status { mpegts_mux_t *ps_mm; TAILQ_HEAD(, psip_table) ps_tables; RB_HEAD(, psip_desc) ps_descs; - gtimer_t ps_reschedule_timer; + mtimer_t ps_reschedule_timer; uint8_t ps_complete; uint8_t ps_armed; } psip_status_t; @@ -87,7 +87,7 @@ psip_status_destroy ( mpegts_table_t *mt ) free(pd->pd_data); free(pd); } - gtimer_disarm(&st->ps_reschedule_timer); + mtimer_disarm(&st->ps_reschedule_timer); free(st); } else { TAILQ_FOREACH(pt, &st->ps_tables, pt_link) @@ -163,7 +163,7 @@ psip_activate_table(psip_status_t *ps, psip_table_t *pt) } ps->ps_refcount++; mt->mt_destroy = psip_status_destroy; - pt->pt_start = dispatch_clock; + pt->pt_start = mdispatch_clock; pt->pt_table = mt; tvhtrace("psip", "table activated - pid 0x%04X type 0x%04X", mt->mt_pid, pt->pt_type); return mt; @@ -203,7 +203,7 @@ psip_reschedule_tables(psip_status_t *ps) total = 0; TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) { total++; - if (pt->pt_table && pt->pt_start + 10 < dispatch_clock) { + if (pt->pt_table && pt->pt_start + mono4sec(10) < mdispatch_clock) { 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; @@ -222,7 +222,7 @@ psip_reschedule_tables(psip_status_t *ps) #if 0 for (i = 0; i < total; i++) { pt = tables[i]; - tvhtrace("psip", "sorted: pid = 0x%04X, type = 0x%04X, time = %"PRItime_t", complete %d\n", + tvhtrace("psip", "sorted: pid = 0x%04X, type = 0x%04X, time = %"PRId64", complete %d\n", pt->pt_pid, pt->pt_type, pt->pt_start, pt->pt_complete); } #endif @@ -260,7 +260,7 @@ psip_complete_table(psip_status_t *ps, mpegts_table_t *mt) mpegts_table_destroy(mt); if (pt) - gtimer_arm(&ps->ps_reschedule_timer, psip_reschedule_tables_cb, ps, 0); + mtimer_arm_rel(&ps->ps_reschedule_timer, psip_reschedule_tables_cb, ps, 0); if (ps->ps_ota == NULL) return; @@ -268,7 +268,7 @@ psip_complete_table(psip_status_t *ps, mpegts_table_t *mt) if (ps->ps_complete) { if (!ps->ps_armed) { ps->ps_armed = 1; - gtimer_arm(&ps->ps_reschedule_timer, psip_reschedule_tables_cb, ps, 10); + mtimer_arm_rel(&ps->ps_reschedule_timer, psip_reschedule_tables_cb, ps, mono4sec(10)); } return; } diff --git a/src/epggrab/module/pyepg.c b/src/epggrab/module/pyepg.c index 54cc37f4f..9ea15a9dd 100644 --- a/src/epggrab/module/pyepg.c +++ b/src/epggrab/module/pyepg.c @@ -377,7 +377,7 @@ static int _pyepg_parse_schedule HTSMSG_FOREACH(f, tags) { if (strcmp(f->hmf_name, "broadcast") == 0) { - ec->laststamp = dispatch_clock; + ec->laststamp = gdispatch_clock; LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { ch = (channel_t *)ilm->ilm_in2; if (!ch->ch_enabled || ch->ch_epg_parent) continue; diff --git a/src/epggrab/module/xmltv.c b/src/epggrab/module/xmltv.c index d1da228d4..95f638ccf 100644 --- a/src/epggrab/module/xmltv.c +++ b/src/epggrab/module/xmltv.c @@ -613,9 +613,9 @@ static int _xmltv_parse_programme (attribs = htsmsg_get_map(subtag, "attrib")) != NULL) icon = htsmsg_get_str(attribs, "src"); - if(stop <= start || stop <= dispatch_clock) return 0; + if(stop <= start || stop <= gdispatch_clock) return 0; - ec->laststamp = dispatch_clock; + ec->laststamp = gdispatch_clock; LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { ch = (channel_t *)ilm->ilm_in2; if (!ch->ch_enabled || ch->ch_epg_parent) continue; @@ -642,7 +642,7 @@ static int _xmltv_parse_channel 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 = dispatch_clock; + ch->laststamp = gdispatch_clock; stats->channels.total++; if (save) stats->channels.created++; diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index c54909c92..a1293ee1d 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -48,7 +48,7 @@ RB_HEAD(,epggrab_ota_mux) epggrab_ota_all; epggrab_ota_head_t epggrab_ota_pending; epggrab_ota_head_t epggrab_ota_active; -gtimer_t epggrab_ota_kick_timer; +mtimer_t epggrab_ota_kick_timer; gtimer_t epggrab_ota_start_timer; int epggrab_ota_running; @@ -161,7 +161,7 @@ epggrab_ota_kick ( int delay ) if (TAILQ_EMPTY(&epggrab_ota_pending)) return; - gtimer_arm(&epggrab_ota_kick_timer, epggrab_ota_kick_cb, NULL, delay); + mtimer_arm_rel(&epggrab_ota_kick_timer, epggrab_ota_kick_cb, NULL, mono4sec(delay)); } static void @@ -184,8 +184,8 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) mpegts_mux_nice_name(mm, name, sizeof(name)); tvhdebug("epggrab", "grab done for %s (%s)", name, reasons[reason]); - gtimer_disarm(&om->om_timer); - gtimer_disarm(&om->om_data_timer); + mtimer_disarm(&om->om_timer); + mtimer_disarm(&om->om_data_timer); assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE); TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link); @@ -243,10 +243,10 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm ) TAILQ_INSERT_TAIL(&epggrab_ota_active, om, om_q_link); om->om_q_type = EPGGRAB_OTA_MUX_ACTIVE; grace = mpegts_input_grace(mmi->mmi_input, mm); - gtimer_arm(&om->om_timer, epggrab_ota_timeout_cb, om, - epggrab_ota_timeout_get() + grace); - gtimer_arm(&om->om_data_timer, epggrab_ota_data_timeout_cb, om, - 30 + grace); /* 30 seconds to receive any EPG info */ + mtimer_arm_rel(&om->om_timer, epggrab_ota_timeout_cb, om, + mono4sec(epggrab_ota_timeout_get() + grace)); + mtimer_arm_rel(&om->om_data_timer, epggrab_ota_data_timeout_cb, om, + mono4sec(30 + grace)); /* 30 seconds to receive any EPG info */ if (modname) { LIST_FOREACH(m, &epggrab_modules, link) if (!strcmp(m->id, modname)) { @@ -625,7 +625,7 @@ static void epggrab_ota_next_arm( time_t next ) { tvhtrace("epggrab", "next ota start event in %li seconds", next - time(NULL)); - gtimer_arm_abs(&epggrab_ota_start_timer, epggrab_ota_start_cb, NULL, next); + gtimer_arm_absn(&epggrab_ota_start_timer, epggrab_ota_start_cb, NULL, next); dbus_emit_signal_s64("/epggrab/ota", "next", next); } @@ -641,7 +641,7 @@ epggrab_ota_start_cb ( void *p ) epggrab_ota_kick(1); pthread_mutex_lock(&epggrab_ota_mutex); - if (!cron_multi_next(epggrab_ota_cron_multi, dispatch_clock, &next)) + if (!cron_multi_next(epggrab_ota_cron_multi, gdispatch_clock, &next)) epggrab_ota_next_arm(next); else tvhwarn("epggrab", "ota cron config invalid or unset"); @@ -887,8 +887,8 @@ epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota ) epggrab_ota_map_t *map; epggrab_ota_svc_link_t *svcl; - gtimer_disarm(&ota->om_timer); - gtimer_disarm(&ota->om_data_timer); + mtimer_disarm(&ota->om_timer); + mtimer_disarm(&ota->om_data_timer); if (head != NULL) TAILQ_REMOVE(head, ota, om_q_link); RB_REMOVE(&epggrab_ota_all, ota, om_global_link); diff --git a/src/htsp_server.c b/src/htsp_server.c index 1d4f9ff1a..ce8b9f330 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -146,7 +146,7 @@ typedef struct htsp_connection { int64_t htsp_epg_window; // only send async epg updates within this window (seconds) int64_t htsp_epg_lastupdate; // last update time for async epg events - gtimer_t htsp_epg_timer; // timer for async epg updates + mtimer_t htsp_epg_timer; // timer for async epg updates /** * Async mode @@ -194,14 +194,14 @@ typedef struct htsp_subscription { th_subscription_t *hs_s; // Temporary int hs_s_bytes_out; - gtimer_t hs_s_bytes_out_timer; + mtimer_t hs_s_bytes_out_timer; streaming_target_t hs_input; profile_chain_t hs_prch; htsp_msg_q_t hs_q; - time_t hs_last_report; /* Last queue status report sent */ + int64_t hs_last_report; /* Last queue status report sent */ int hs_dropstats[PKT_NTYPES]; @@ -358,7 +358,7 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs) th_subscription_t *ts = hs->hs_s; hs->hs_s = NULL; - gtimer_disarm(&hs->hs_s_bytes_out_timer); + mtimer_disarm(&hs->hs_s_bytes_out_timer); LIST_REMOVE(hs, hs_link); LIST_INSERT_HEAD(&htsp->htsp_dead_subscriptions, hs, hs_link); @@ -1407,9 +1407,9 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) 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-dispatch_clock; - } else if (epgMaxTime > dispatch_clock) { - htsp->htsp_epg_window = epgMaxTime-dispatch_clock; + htsp->htsp_epg_window = epgMaxTime-gdispatch_clock; + } else if (epgMaxTime > gdispatch_clock) { + htsp->htsp_epg_window = epgMaxTime-gdispatch_clock; } else { htsp->htsp_epg_window = 0; } @@ -2331,7 +2331,7 @@ static void _bytes_out_cb(void *aux) htsp_subscription_t *hs = aux; if (hs->hs_s) { subscription_add_bytes_out(hs->hs_s, atomic_exchange(&hs->hs_s_bytes_out, 0)); - gtimer_arm_ms(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, 200); + mtimer_arm_rel(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, mono4ms(200)); } } @@ -2446,7 +2446,7 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) htsp->htsp_clientname, NULL); if (hs->hs_s) - gtimer_arm_ms(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, 200); + mtimer_arm_rel(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, mono4ms(200)); return NULL; } @@ -3253,7 +3253,7 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, if(htsp.htsp_async_mode) LIST_REMOVE(&htsp, htsp_async_link); - gtimer_disarm(&htsp.htsp_epg_timer); + mtimer_disarm(&htsp.htsp_epg_timer); /* deregister this client */ LIST_REMOVE(&htsp, htsp_link); @@ -3663,7 +3663,7 @@ htsp_epg_send_waiting(htsp_connection_t *htsp, int64_t mintime) channel_t *ch; int64_t maxtime; - maxtime = dispatch_clock + htsp->htsp_epg_window; + maxtime = gdispatch_clock + htsp->htsp_epg_window; htsp->htsp_epg_lastupdate = maxtime; /* Push new events */ @@ -3679,7 +3679,8 @@ htsp_epg_send_waiting(htsp_connection_t *htsp, int64_t mintime) /* Keep the epg window up to date */ if (htsp->htsp_epg_window) - gtimer_arm(&htsp->htsp_epg_timer, htsp_epg_window_cb, htsp, HTSP_ASYNC_EPG_INTERVAL); + mtimer_arm_rel(&htsp->htsp_epg_timer, htsp_epg_window_cb, + htsp, mono4sec(HTSP_ASYNC_EPG_INTERVAL)); } /** @@ -3808,11 +3809,11 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_send_subscription(htsp, m, pkt->pkt_payload, hs, payloadlen); atomic_add(&hs->hs_s_bytes_out, payloadlen); - if(hs->hs_last_report != dispatch_clock) { + if(sec4mono(hs->hs_last_report) != sec4mono(mdispatch_clock)) { /* Send a queue and signal status report every second */ - hs->hs_last_report = dispatch_clock; + hs->hs_last_report = mdispatch_clock; m = htsmsg_create_map(); htsmsg_add_str(m, "method", "queueStatus"); diff --git a/src/http.h b/src/http.h index c0b9b52d3..f27a1d909 100644 --- a/src/http.h +++ b/src/http.h @@ -293,7 +293,7 @@ struct http_client { char *hc_data; /* data body */ size_t hc_data_size; /* data body size - result for caller */ - time_t hc_ping_time; /* last issued command */ + int64_t hc_ping_time; /* last issued command */ char *hc_rbuf; /* read buffer */ size_t hc_rsize; /* read buffer size */ @@ -344,7 +344,7 @@ struct http_client { struct http_client_ssl *hc_ssl; /* ssl internals */ - gtimer_t hc_close_timer; + mtimer_t hc_close_timer; /* callbacks */ void (*hc_hdr_create) (http_client_t *hc, http_arg_list_t *h, diff --git a/src/httpc.c b/src/httpc.c index 1fe13cd43..dc760f694 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -645,7 +645,7 @@ error: empty = TAILQ_EMPTY(&hc->hc_wqueue); TAILQ_INSERT_TAIL(&hc->hc_wqueue, wcmd, link); - hc->hc_ping_time = dispatch_clock; + hc->hc_ping_time = mdispatch_clock; if (empty) return http_client_send_partial(hc); diff --git a/src/idnode.c b/src/idnode.c index 2e97f0db3..5c8b81825 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -49,7 +49,7 @@ static TAILQ_HEAD(,idnode_save) idnodes_save; tvh_cond_t save_cond; pthread_t save_tid; static int save_running; -static gtimer_t save_timer; +static mtimer_t save_timer; SKEL_DECLARE(idclasses_skel, idclass_link_t); @@ -1108,9 +1108,9 @@ idnode_save_queue ( idnode_t *self ) return; ise = malloc(sizeof(*ise)); ise->ise_node = self; - ise->ise_reqtime = dispatch_clock; + ise->ise_reqtime = mdispatch_clock; if (TAILQ_EMPTY(&idnodes_save) && save_running) - gtimer_arm(&save_timer, idnode_save_trigger_thread_cb, NULL, IDNODE_SAVE_DELAY); + mtimer_arm_rel(&save_timer, idnode_save_trigger_thread_cb, NULL, IDNODE_SAVE_DELAY); TAILQ_INSERT_TAIL(&idnodes_save, ise, ise_link); self->in_save = ise; } @@ -1699,10 +1699,10 @@ save_thread ( void *aux ) while (save_running) { if ((ise = TAILQ_FIRST(&idnodes_save)) == NULL || - (ise->ise_reqtime + IDNODE_SAVE_DELAY > dispatch_clock)) { + (ise->ise_reqtime + IDNODE_SAVE_DELAY > mdispatch_clock)) { if (ise) - gtimer_arm(&save_timer, idnode_save_trigger_thread_cb, NULL, - (ise->ise_reqtime + IDNODE_SAVE_DELAY) - dispatch_clock); + mtimer_arm_abs(&save_timer, idnode_save_trigger_thread_cb, NULL, + ise->ise_reqtime + IDNODE_SAVE_DELAY); tvh_cond_wait(&save_cond, &global_lock); continue; } @@ -1718,7 +1718,7 @@ save_thread ( void *aux ) pthread_mutex_lock(&global_lock); } - gtimer_disarm(&save_timer); + mtimer_disarm(&save_timer); while ((ise = TAILQ_FIRST(&idnodes_save)) != NULL) { m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); @@ -1762,7 +1762,7 @@ idnode_done(void) save_running = 0; tvh_cond_signal(&save_cond, 0); pthread_join(save_tid, NULL); - gtimer_disarm(&save_timer); + mtimer_disarm(&save_timer); while ((il = RB_FIRST(&idclasses)) != NULL) { RB_REMOVE(&idclasses, il, link); diff --git a/src/idnode.h b/src/idnode.h index 30b5b6a21..3c4f00d31 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -30,7 +30,7 @@ struct access; typedef struct idnode idnode_t; typedef struct idnode_save idnode_save_t; -#define IDNODE_SAVE_DELAY 3 +#define IDNODE_SAVE_DELAY (3 * MONOCLOCK_RESOLUTION) #define SAVEPTR_OUTOFSERVICE ((void *)((intptr_t)-1LL)) @@ -107,7 +107,7 @@ struct idnode { struct idnode_save { TAILQ_ENTRY(idnode_save) ise_link; ///< List chain idnode_t *ise_node; ///< Node owning this - time_t ise_reqtime; ///< First request + int64_t ise_reqtime; ///< First request }; /* diff --git a/src/imagecache.c b/src/imagecache.c index bf9c5440f..634c8a9e0 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -119,7 +119,7 @@ const idclass_t imagecache_class = { static tvh_cond_t imagecache_cond; static TAILQ_HEAD(, imagecache_image) imagecache_queue; -static gtimer_t imagecache_timer; +static mtimer_t imagecache_timer; #endif static int @@ -463,7 +463,7 @@ imagecache_init ( void ) // TODO: this could be more efficient by being targetted, however // the reality its not necessary and I'd prefer to avoid dumping // 100's of timers into the global pool - gtimer_arm(&imagecache_timer, imagecache_timer_cb, NULL, 600); + mtimer_arm_rel(&imagecache_timer, imagecache_timer_cb, NULL, mono4sec(600)); #endif } @@ -493,6 +493,7 @@ imagecache_done ( void ) imagecache_image_t *img; #if ENABLE_IMAGECACHE + mtimer_disarm(&imagecache_timer); tvh_cond_signal(&imagecache_cond, 1); pthread_join(imagecache_tid, NULL); #endif @@ -641,6 +642,7 @@ imagecache_open ( uint32_t id ) imagecache_image_t skel, *i; char *fn; int fd = -1; + int64_t mono; lock_assert(&global_lock); @@ -666,10 +668,12 @@ imagecache_open ( uint32_t id ) /* Wait */ } else if (i->state == FETCHING) { - e = tvh_cond_timedwait(&imagecache_cond, &global_lock, - getmonoclock() + 5 * MONOCLOCK_RESOLUTION); - if (e == ETIMEDOUT) - return -1; + mono = mdispatch_clock + mono4sec(5); + do { + e = tvh_cond_timedwait(&imagecache_cond, &global_lock, mono); + if (e == ETIMEDOUT) + return -1; + } while (ERRNO_AGAIN(e)); /* Attempt to fetch */ } else if (i->state == QUEUED) { diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 252f4397c..b7b38b118 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -320,7 +320,7 @@ struct mpegts_network */ mpegts_mux_queue_t mn_scan_pend; // Pending muxes mpegts_mux_queue_t mn_scan_active; // Active muxes - gtimer_t mn_scan_timer; // Timer for activity + mtimer_t mn_scan_timer; // Timer for activity /* * Functions @@ -415,7 +415,7 @@ struct mpegts_mux uint16_t mm_tsid; int mm_update_pids_flag; - gtimer_t mm_update_pids_timer; + mtimer_t mm_update_pids_timer; /* * Services @@ -431,7 +431,7 @@ struct mpegts_mux int mm_scan_weight; ///< Scan priority int mm_scan_flags; ///< Subscription flags int mm_scan_init; ///< Flag to timeout handler - gtimer_t mm_scan_timeout; ///< Timer to handle timeout + mtimer_t mm_scan_timeout; ///< Timer to handle timeout TAILQ_ENTRY(mpegts_mux) mm_scan_link; ///< Link to Queue mpegts_mux_scan_state_t mm_scan_state; ///< Scanning state @@ -443,7 +443,7 @@ struct mpegts_mux } mm_dmc_origin2; #endif void *mm_dmc_origin; - time_t mm_dmc_origin_expire; + int64_t mm_dmc_origin_expire; char *mm_fastscan_muxes; @@ -591,11 +591,6 @@ struct mpegts_service sbuf_t s_tsbuf; time_t s_tsbuf_last; - /** - * Average continuity errors - */ - avgstat_t s_cc_errors; - /** * PCR drift compensation. This should really be per-packet. */ @@ -670,7 +665,7 @@ struct mpegts_input /* * Status */ - gtimer_t mi_status_timer; + mtimer_t mi_status_timer; /* * Input processing diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index d8b1f7e31..6b803597e 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -118,7 +118,7 @@ dvb_service_autoenable( mpegts_service_t *s, const char *where ) 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 = dispatch_clock; + s->s_dvb_check_seen = gdispatch_clock; } #if ENABLE_MPEGTS_DVB @@ -2452,11 +2452,11 @@ static void dvb_time_update(const uint8_t *ptr, const char *srcname) { static time_t dvb_last_update = 0; time_t t; - if (dvb_last_update + 1800 < dispatch_clock) { + if (dvb_last_update + 1800 < gdispatch_clock) { t = dvb_convert_date(ptr, 0); if (t > 0) { tvhtime_update(t, srcname); - dvb_last_update = dispatch_clock; + dvb_last_update = gdispatch_clock; } } } diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 1cc589eaf..1cb88cf03 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -117,7 +117,7 @@ iptv_bouquet_update(void *aux) void iptv_bouquet_trigger(iptv_network_t *in, int timeout) { - gtimer_arm(&in->in_bouquet_timer, iptv_bouquet_update, in, timeout); + mtimer_arm_rel(&in->in_bouquet_timer, iptv_bouquet_update, in, mono4sec(timeout)); } void @@ -369,7 +369,7 @@ iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) pthread_mutex_lock(&iptv_lock); - gtimer_disarm(&im->im_pause_timer); + mtimer_disarm(&im->im_pause_timer); /* Stop */ if (im->im_handler->stop) @@ -420,7 +420,7 @@ iptv_input_pause_check ( iptv_mux_t *im ) if (limit == UINT32_MAX) return 0; limit *= 1000; - s64 = getmonoclock() - im->im_pcr_start; + s64 = getfastmonoclock() - im->im_pcr_start; im->im_pcr_start += s64; im->im_pcr += (((s64 / 10LL) * 9LL) + 4LL) / 10LL; im->im_pcr &= PTS_MASK; @@ -446,7 +446,7 @@ iptv_input_unpause ( void *aux ) } pthread_mutex_unlock(&iptv_lock); if (pause) - gtimer_arm(&im->im_pause_timer, iptv_input_unpause, im, 1); + mtimer_arm_rel(&im->im_pause_timer, iptv_input_unpause, im, mono4sec(1)); } static void * @@ -492,7 +492,7 @@ iptv_input_thread ( void *aux ) if (r == 1) { pthread_mutex_lock(&global_lock); if (im->mm_active) - gtimer_arm(&im->im_pause_timer, iptv_input_unpause, im, 1); + mtimer_arm_rel(&im->im_pause_timer, iptv_input_unpause, im, mono4sec(1)); pthread_mutex_unlock(&global_lock); } } @@ -567,7 +567,7 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) s64 = pts_diff(pcr.pcr_first, pcr.pcr_last); if (s64 != PTS_UNSET) { im->im_pcr = pcr.pcr_first; - im->im_pcr_start = getmonoclock(); + im->im_pcr_start = getfastmonoclock(); im->im_pcr_end = im->im_pcr_start + ((s64 * 100LL) + 50LL) / 9LL; tvhtrace("iptv-pcr", "pcr: first %"PRId64" last %"PRId64", time start %"PRId64", end %"PRId64, pcr.pcr_first, pcr.pcr_last, im->im_pcr_start, im->im_pcr_end); @@ -660,7 +660,7 @@ iptv_network_delete ( mpegts_network_t *mn, int delconf ) idnode_save_check(&mn->mn_id, delconf); - gtimer_disarm(&in->in_bouquet_timer); + mtimer_disarm(&in->in_bouquet_timer); if (in->mn_id.in_class == &iptv_auto_network_class) iptv_auto_network_done(in); diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 2a4b80bf2..7519aeac2 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -30,7 +30,7 @@ typedef struct auto_private { iptv_network_t *in_network; download_t in_download; - gtimer_t in_auto_timer; + mtimer_t in_auto_timer; } auto_private_t; /* @@ -384,7 +384,7 @@ static void iptv_auto_network_stop( void *aux ) { auto_private_t *ap = aux; - gtimer_disarm(&ap->in_auto_timer); + mtimer_disarm(&ap->in_auto_timer); } /* @@ -397,8 +397,8 @@ iptv_auto_network_trigger0(void *aux) iptv_network_t *in = ap->in_network; download_start(&ap->in_download, in->in_url, ap); - gtimer_arm(&ap->in_auto_timer, iptv_auto_network_trigger0, ap, - MAX(1, in->in_refetch_period) * 60); + mtimer_arm_rel(&ap->in_auto_timer, iptv_auto_network_trigger0, ap, + mono4sec(MAX(1, in->in_refetch_period) * 60)); } /* @@ -437,7 +437,7 @@ iptv_auto_network_done( iptv_network_t *in ) { auto_private_t *ap = in->in_auto; in->in_auto = NULL; - gtimer_disarm(&ap->in_auto_timer); + mtimer_disarm(&ap->in_auto_timer); download_done(&ap->in_download); free(ap); } diff --git a/src/input/mpegts/iptv/iptv_file.c b/src/input/mpegts/iptv/iptv_file.c index 6470482e9..ee9ff4bd0 100644 --- a/src/input/mpegts/iptv/iptv_file.c +++ b/src/input/mpegts/iptv/iptv_file.c @@ -42,12 +42,12 @@ iptv_file_thread ( void *aux ) { iptv_mux_t *im = aux; file_priv_t *fp = im->im_data; - struct timespec ts; ssize_t r; int fd = fp->fd, pause = 0; char buf[32*1024]; off_t off = 0; - int n; + int64_t mono; + int e; #if defined(PLATFORM_DARWIN) fcntl(fd, F_NOCACHE, 1); @@ -55,12 +55,12 @@ iptv_file_thread ( void *aux ) pthread_mutex_lock(&iptv_lock); while (!fp->shutdown && fd > 0) { while (!fp->shutdown && pause) { - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 1; - n = tvh_cond_timedwait(&fp->cond, &iptv_lock, - getmonoclock() + 1 * MONOCLOCK_RESOLUTION); - if (n == ETIMEDOUT) - break; + mono = mdispatch_clock + mono4sec(1); + do { + e = tvh_cond_timedwait(&fp->cond, &iptv_lock, mono); + if (e == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(e)); } if (fp->shutdown) break; diff --git a/src/input/mpegts/iptv/iptv_http.c b/src/input/mpegts/iptv/iptv_http.c index 647e37d41..7898b77ec 100644 --- a/src/input/mpegts/iptv/iptv_http.c +++ b/src/input/mpegts/iptv/iptv_http.c @@ -47,7 +47,7 @@ typedef struct http_priv { htsmsg_t *hls_m3u; htsmsg_t *hls_key; uint8_t *hls_si; - time_t hls_last_si; + int64_t hls_last_si; struct { char tmp[AES_BLOCK_SIZE]; int tmp_len; @@ -323,14 +323,14 @@ iptv_http_data memcpy(hp->hls_si, buf, 2*188); } - if (dispatch_clock != hp->hls_last_si && hp->hls_si) { + if (hp->hls_last_si + mono4sec(1) <= mdispatch_clock && 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 = dispatch_clock; + hp->hls_last_si = mdispatch_clock; sbuf_append(&im->mm_iptv_buffer, tsbuf, rem); hp->off += rem; } @@ -344,7 +344,7 @@ iptv_http_data if (pause && iptv_http_safe_global_lock(hp)) { if (im->mm_active && !hp->shutdown) - gtimer_arm(&im->im_pause_timer, iptv_input_unpause, im, 1); + mtimer_arm_rel(&im->im_pause_timer, iptv_input_unpause, im, mono4sec(1)); pthread_mutex_unlock(&global_lock); } return 0; diff --git a/src/input/mpegts/iptv/iptv_pipe.c b/src/input/mpegts/iptv/iptv_pipe.c index 4902c5208..2fc52717e 100644 --- a/src/input/mpegts/iptv/iptv_pipe.c +++ b/src/input/mpegts/iptv/iptv_pipe.c @@ -62,7 +62,7 @@ iptv_pipe_start ( iptv_mux_t *im, const char *raw, const url_t *url ) im->mm_iptv_fd = rd; im->im_data = (void *)(intptr_t)pid; - im->mm_iptv_respawn_last = dispatch_clock; + im->mm_iptv_respawn_last = mdispatch_clock; if (url) iptv_input_mux_started(im); @@ -123,7 +123,7 @@ iptv_pipe_read ( iptv_mux_t *im ) spawn_kill(pid, iptv_pipe_kill_sig(im), im->mm_iptv_kill_timeout); im->mm_iptv_fd = -1; im->im_data = NULL; - if (dispatch_clock < im->mm_iptv_respawn_last + 2) { + if (mdispatch_clock < im->mm_iptv_respawn_last + mono4sec(2)) { tvherror("iptv", "stdin pipe unexpectedly closed: %s", r < 0 ? strerror(errno) : "No data"); } else { @@ -136,7 +136,7 @@ iptv_pipe_read ( iptv_mux_t *im ) tvherror("iptv", "unable to respawn %s", im->mm_iptv_url_raw); } else { iptv_input_fd_started(im); - im->mm_iptv_respawn_last = dispatch_clock; + im->mm_iptv_respawn_last = mdispatch_clock; } } pthread_mutex_unlock(&iptv_lock); diff --git a/src/input/mpegts/iptv/iptv_private.h b/src/input/mpegts/iptv/iptv_private.h index 2188adbc2..f0d96edf9 100644 --- a/src/input/mpegts/iptv/iptv_private.h +++ b/src/input/mpegts/iptv/iptv_private.h @@ -93,7 +93,7 @@ struct iptv_network char *in_url; char *in_url_sane; int in_bouquet; - gtimer_t in_bouquet_timer; + mtimer_t in_bouquet_timer; char *in_ctx_charset; int64_t in_channel_number; uint32_t in_refetch_period; @@ -147,7 +147,7 @@ struct iptv_mux uint32_t mm_iptv_buffer_limit; iptv_handler_t *im_handler; - gtimer_t im_pause_timer; + mtimer_t im_pause_timer; int64_t im_pcr; int64_t im_pcr_start; diff --git a/src/input/mpegts/iptv/iptv_rtsp.c b/src/input/mpegts/iptv/iptv_rtsp.c index 6fd0f6acc..b70d798f3 100644 --- a/src/input/mpegts/iptv/iptv_rtsp.c +++ b/src/input/mpegts/iptv/iptv_rtsp.c @@ -30,7 +30,7 @@ typedef struct { udp_multirecv_t um; char *path; char *query; - gtimer_t alive_timer; + mtimer_t alive_timer; int play; iptv_rtcp_info_t * rtcp_info; } rtsp_priv_t; @@ -54,8 +54,8 @@ iptv_rtsp_alive_cb ( void *aux ) rtsp_priv_t *rp = im->im_data; rtsp_send(rp->hc, RTSP_CMD_OPTIONS, rp->path, rp->query, NULL); - gtimer_arm(&rp->alive_timer, iptv_rtsp_alive_cb, im, - MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1)); + mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, + mono4sec(MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1))); } /* @@ -72,7 +72,7 @@ iptv_rtsp_header ( http_client_t *hc ) /* teardown (or teardown timeout) */ if (hc->hc_cmd == RTSP_CMD_TEARDOWN) { pthread_mutex_lock(&global_lock); - gtimer_arm(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0); + mtimer_arm_rel(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0); pthread_mutex_unlock(&global_lock); } return 0; @@ -102,8 +102,8 @@ iptv_rtsp_header ( http_client_t *hc ) hc->hc_cmd = HTTP_CMD_NONE; pthread_mutex_lock(&global_lock); iptv_input_mux_started(hc->hc_aux); - gtimer_arm(&rp->alive_timer, iptv_rtsp_alive_cb, im, - MAX(1, (hc->hc_rtp_timeout / 2) - 1)); + mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, + mono4sec(MAX(1, (hc->hc_rtp_timeout / 2) - 1))); pthread_mutex_unlock(&global_lock); break; default: @@ -213,7 +213,7 @@ iptv_rtsp_stop if (play) rtsp_teardown(rp->hc, rp->path, ""); pthread_mutex_unlock(&iptv_lock); - gtimer_disarm(&rp->alive_timer); + mtimer_disarm(&rp->alive_timer); udp_multirecv_free(&rp->um); if (!play) http_client_close(rp->hc); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_ca.c b/src/input/mpegts/linuxdvb/linuxdvb_ca.c index 517513f68..c14d22964 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_ca.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_ca.c @@ -765,7 +765,7 @@ linuxdvb_ca_monitor ( void *aux ) } - gtimer_arm_ms(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, 250); + mtimer_arm_rel(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, mono4ms(250)); } linuxdvb_ca_t * @@ -806,7 +806,7 @@ linuxdvb_ca_create TAILQ_INIT(&lca->lca_capmt_queue); - gtimer_arm_ms(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, 250); + mtimer_arm_rel(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, mono4ms(250)); return lca; } @@ -868,8 +868,8 @@ done: free(lcc); if (!TAILQ_EMPTY(&lca->lca_capmt_queue)) { - gtimer_arm_ms(&lca->lca_capmt_queue_timer, - linuxdvb_ca_process_capmt_queue, lca, i); + mtimer_arm_rel(&lca->lca_capmt_queue_timer, + linuxdvb_ca_process_capmt_queue, lca, mono4ms(i)); } } @@ -905,8 +905,8 @@ linuxdvb_ca_enqueue_capmt(linuxdvb_ca_t *lca, uint8_t slot, const uint8_t *ptr, ca_pmt_list_mgmt2str(lcc->list_mgmt)); } - gtimer_arm_ms(&lca->lca_capmt_queue_timer, - linuxdvb_ca_process_capmt_queue, lca, 50); + mtimer_arm_rel(&lca->lca_capmt_queue_timer, + linuxdvb_ca_process_capmt_queue, lca, mono4ms(50)); } void linuxdvb_ca_save( linuxdvb_ca_t *lca, htsmsg_t *msg ) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index e34fb01d3..a2a4e5bdc 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -416,7 +416,7 @@ linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi ) if (lfe->lfe_satconf) linuxdvb_satconf_reset(lfe->lfe_satconf); } - gtimer_disarm(&lfe->lfe_monitor_timer); + mtimer_disarm(&lfe->lfe_monitor_timer); /* Ensure FE opened (if not powersave) */ } else if (!lfe->lfe_powersave && lfe->lfe_fe_fd <= 0 && lfe->lfe_fe_path) { @@ -529,7 +529,7 @@ linuxdvb_frontend_stop_mux lfe->lfe_status2 = 0; /* Ensure it won't happen immediately */ - gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 2); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, mono4sec(2)); if (lfe->lfe_satconf && lfe->lfe_refcount == 1) linuxdvb_satconf_post_stop_mux(lfe->lfe_satconf); @@ -546,7 +546,7 @@ linuxdvb_frontend_stop_mux lfe2->lfe_status = 0; lfe2->lfe_status2 = 0; /* Ensure it won't happen immediately */ - gtimer_arm(&lfe2->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 2); + mtimer_arm_rel(&lfe2->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, mono4sec(2)); if (lfe2->lfe_satconf) linuxdvb_satconf_post_stop_mux(lfe2->lfe_satconf); lfe2->lfe_in_setup = 0; @@ -674,7 +674,7 @@ linuxdvb_frontend_monitor ( void *aux ) signal_status_t sigstat; streaming_message_t sm; service_t *s; - int logit = 0, retune; + int logit = 0, retune, e; uint32_t period = MINMAX(lfe->lfe_status_period, 250, 8000); #if DVB_VER_ATLEAST(5,10) struct dtv_property fe_properties[6]; @@ -711,7 +711,7 @@ linuxdvb_frontend_monitor ( void *aux ) if (!mmi || !lfe->lfe_ready) return; /* re-arm */ - gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, period); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, mono4ms(period)); /* Get current status */ if (ioctl(lfe->lfe_fe_fd, FE_READ_STATUS, &fe_status) == -1) { @@ -751,7 +751,7 @@ linuxdvb_frontend_monitor ( void *aux ) if (lfe->lfe_locked && lfe->lfe_freq > 0) { tvhlog(LOG_WARNING, "linuxdvb", "%s - %s", buf, retune ? "retune" : "retune nodata"); linuxdvb_frontend_tune0(lfe, mmi, lfe->lfe_freq); - gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 50); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, mono4ms(50)); lfe->lfe_locked = 1; } } @@ -772,7 +772,11 @@ linuxdvb_frontend_monitor ( void *aux ) pthread_mutex_lock(&lfe->lfe_dvr_lock); tvhthread_create(&lfe->lfe_dvr_thread, NULL, linuxdvb_frontend_input_thread, lfe, "lnxdvb-front"); - tvh_cond_wait(&lfe->lfe_dvr_cond, &lfe->lfe_dvr_lock); + do { + e = tvh_cond_wait(&lfe->lfe_dvr_cond, &lfe->lfe_dvr_lock); + if (e == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(e)); pthread_mutex_unlock(&lfe->lfe_dvr_lock); /* Table handlers */ @@ -781,18 +785,18 @@ linuxdvb_frontend_monitor ( void *aux ) /* Re-arm (quick) */ } else { - gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, - lfe, 50); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, + lfe, mono4ms(50)); /* Monitor 1 per sec */ - if (dispatch_clock < lfe->lfe_monitor) + if (mdispatch_clock < lfe->lfe_monitor) return; - lfe->lfe_monitor = dispatch_clock + 1; + lfe->lfe_monitor = mdispatch_clock + mono4sec(1); } } else { - if (dispatch_clock < lfe->lfe_monitor) + if (mdispatch_clock < lfe->lfe_monitor) return; - lfe->lfe_monitor = dispatch_clock + (period + 999) / 1000; + lfe->lfe_monitor = mdispatch_clock + mono4sec((period + 999) / 1000); } /* Statistics - New API */ @@ -1762,7 +1766,7 @@ linuxdvb_frontend_tune1 if (!r) { time(&lfe->lfe_monitor); lfe->lfe_monitor += 4; - gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 50); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, mono4ms(50)); lfe->lfe_ready = 1; } @@ -2005,7 +2009,7 @@ linuxdvb_frontend_delete ( linuxdvb_frontend_t *lfe ) mpegts_input_stop_all((mpegts_input_t*)lfe); /* Stop monitor */ - gtimer_disarm(&lfe->lfe_monitor_timer); + mtimer_disarm(&lfe->lfe_monitor_timer); /* Close FDs */ if (lfe->lfe_fe_fd > 0) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index e1300f55e..276b3f964 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -143,7 +143,7 @@ struct linuxdvb_frontend int lfe_nodata; int lfe_freq; time_t lfe_monitor; - gtimer_t lfe_monitor_timer; + mtimer_t lfe_monitor_timer; tvhlog_limit_t lfe_status_log; /* @@ -181,8 +181,8 @@ struct linuxdvb_ca int lca_enabled; int lca_high_bitrate_mode; int lca_capmt_query; - gtimer_t lca_monitor_timer; - gtimer_t lca_capmt_queue_timer; + mtimer_t lca_monitor_timer; + mtimer_t lca_capmt_queue_timer; int lca_capmt_interval; int lca_capmt_query_interval; pthread_t lca_en50221_thread; @@ -242,7 +242,7 @@ struct linuxdvb_satconf /* * Diseqc handling */ - gtimer_t ls_diseqc_timer; + mtimer_t ls_diseqc_timer; int ls_diseqc_idx; int ls_diseqc_repeats; int ls_diseqc_full; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 93b6278b3..6b1080ad2 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -709,7 +709,7 @@ linuxdvb_satconf_post_stop_mux ( linuxdvb_satconf_t *ls ) { ls->ls_mmi = NULL; - gtimer_disarm(&ls->ls_diseqc_timer); + mtimer_disarm(&ls->ls_diseqc_timer); if (ls->ls_frontend && ls->ls_lnb_poweroff) { linuxdvb_diseqc_set_volt(ls, -1); linuxdvb_satconf_reset(ls); @@ -825,7 +825,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Pending */ if (r != 0) { tvhtrace("diseqc", "waiting %d seconds to finish setup for %s", r, lds[i]->ld_type); - gtimer_arm(&ls->ls_diseqc_timer, linuxdvb_satconf_ele_tune_cb, lse, r); + mtimer_arm_rel(&ls->ls_diseqc_timer, linuxdvb_satconf_ele_tune_cb, lse, mono4sec(r)); ls->ls_diseqc_idx = i + 1; return 0; } @@ -1457,7 +1457,7 @@ linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls, int delconf ) char ubuf[UUID_HEX_SIZE]; if (delconf) hts_settings_remove("input/linuxdvb/satconfs/%s", idnode_uuid_as_str(&ls->ls_id, ubuf)); - gtimer_disarm(&ls->ls_diseqc_timer); + mtimer_disarm(&ls->ls_diseqc_timer); for (lse = TAILQ_FIRST(&ls->ls_elements); lse != NULL; lse = nxt) { nxt = TAILQ_NEXT(lse, lse_link); linuxdvb_satconf_ele_destroy(lse); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 2e4eae20f..37832eb09 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -861,8 +861,7 @@ mpegts_input_started_mux /* Arm timer */ if (LIST_FIRST(&mi->mi_mux_active) == NULL) - gtimer_arm(&mi->mi_status_timer, mpegts_input_status_timer, - mi, 1); + mtimer_arm_rel(&mi->mi_status_timer, mpegts_input_status_timer, mi, mono4sec(1)); /* Update */ mmi->mmi_mux->mm_active = mmi; @@ -900,7 +899,7 @@ mpegts_input_stopped_mux /* Disarm timer */ if (LIST_FIRST(&mi->mi_mux_active) == NULL) - gtimer_disarm(&mi->mi_status_timer); + mtimer_disarm(&mi->mi_status_timer); mi->mi_display_name(mi, buf, sizeof(buf)); tvhtrace("mpegts", "%s - flush subscribers", buf); @@ -1054,10 +1053,10 @@ mpegts_input_recv_packets if (len < (MIN_TS_PKT * 188) && (flags & MPEGTS_DATA_CC_RESTART) == 0) { /* For slow streams, check also against the clock */ - if (dispatch_clock == mi->mi_last_dispatch) + if (sec4mono(mdispatch_clock) == sec4mono(mi->mi_last_dispatch)) return; } - mi->mi_last_dispatch = dispatch_clock; + mi->mi_last_dispatch = mdispatch_clock; /* Check for sync */ while ( (len >= MIN_TS_SYN) && @@ -1738,7 +1737,7 @@ mpegts_input_status_timer ( void *p ) tvh_input_stream_destroy(&st); } pthread_mutex_unlock(&mi->mi_output_lock); - gtimer_arm(&mi->mi_status_timer, mpegts_input_status_timer, mi, 1); + mtimer_arm_rel(&mi->mi_status_timer, mpegts_input_status_timer, mi, mono4sec(1)); mpegts_input_dbus_notify(mi, subs); } diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index d3c98080a..b646311da 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -95,7 +95,7 @@ mpegts_mux_scan_active t = mpegts_input_grace(mi, mm); /* Setup timeout */ - gtimer_arm(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, t); + mtimer_arm_rel(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, mono4sec(t)); } } @@ -691,7 +691,7 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) } /* Stop PID timer */ - gtimer_disarm(&mm->mm_update_pids_timer); + mtimer_disarm(&mm->mm_update_pids_timer); /* Free memory */ idnode_save_check(&mm->mm_id, 1); @@ -859,7 +859,7 @@ void mpegts_mux_update_pids ( mpegts_mux_t *mm ) { if (mm && mm->mm_active) - gtimer_arm(&mm->mm_update_pids_timer, mpegts_mux_update_pids_cb, mm, 0); + mtimer_arm_rel(&mm->mm_update_pids_timer, mpegts_mux_update_pids_cb, mm, 0); } void @@ -1090,7 +1090,7 @@ again: /* Pending tables (another 20s or 30s - bit arbitrary) */ } else if (q) { tvhtrace("mpegts", "%s - scan needs more time", buf); - gtimer_arm(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, w ? 30 : 20); + mtimer_arm_rel(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, mono4sec(w ? 30 : 20)); return; /* Complete */ diff --git a/src/input/mpegts/mpegts_mux_sched.c b/src/input/mpegts/mpegts_mux_sched.c index 1a20181bf..756ec9a63 100644 --- a/src/input/mpegts/mpegts_mux_sched.c +++ b/src/input/mpegts/mpegts_mux_sched.c @@ -47,14 +47,14 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) if (mms->mms_timeout <= 0) gtimer_disarm(&mms->mms_timer); else { - gtimer_arm(&mms->mms_timer, mpegts_mux_sched_timer, mms, - mms->mms_timeout); + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, + mms->mms_timeout); } } else { time_t now, nxt; time(&now); if (!cron_next(&mms->mms_cronjob, now, &nxt)) { - gtimer_arm_abs(&mms->mms_timer, mpegts_mux_sched_timer, mms, nxt); + gtimer_arm_absn(&mms->mms_timer, mpegts_mux_sched_timer, mms, nxt); } } } @@ -176,7 +176,7 @@ mpegts_mux_sched_input ( void *p, streaming_message_t *sm ) switch (sm->sm_type) { case SMT_STOP: - gtimer_arm(&mms->mms_timer, mpegts_mux_sched_timer, mms, 0); + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, 0); break; default: // ignore @@ -231,14 +231,14 @@ mpegts_mux_sched_timer ( void *p ) /* Failed (try-again soon) */ if (!mms->mms_sub) { - gtimer_arm(&mms->mms_timer, mpegts_mux_sched_timer, mms, 60); + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, 60); /* OK */ } else { mms->mms_active = 1; if (mms->mms_timeout > 0) { - gtimer_arm(&mms->mms_timer, mpegts_mux_sched_timer, mms, - mms->mms_timeout); + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, + mms->mms_timeout); } } @@ -257,7 +257,7 @@ mpegts_mux_sched_timer ( void *p ) } /* Timer */ - gtimer_arm_abs(&mms->mms_timer, mpegts_mux_sched_timer, mms, nxt); + gtimer_arm_absn(&mms->mms_timer, mpegts_mux_sched_timer, mms, nxt); } } diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index fde8deca4..299eca1e6 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -368,7 +368,7 @@ mpegts_network_delete } /* Disarm scanning */ - gtimer_disarm(&mn->mn_scan_timer); + mtimer_disarm(&mn->mn_scan_timer); /* Remove from input */ while ((mnl = LIST_FIRST(&mn->mn_inputs))) @@ -418,7 +418,7 @@ mpegts_network_create0 /* Initialise scanning */ TAILQ_INIT(&mn->mn_scan_pend); TAILQ_INIT(&mn->mn_scan_active); - gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); /* Defaults */ mn->mn_satpos = INT_MAX; diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index cff0010e5..22b144db1 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -661,7 +661,7 @@ dvb_network_create_mux 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 > dispatch_clock && mm->mm_dmc_origin && mm->mm_dmc_origin != origin) + if (mm->mm_dmc_origin_expire > mdispatch_clock && mm->mm_dmc_origin && mm->mm_dmc_origin != origin) goto noop; #define COMPARE(x, cbit) ({ \ int xr = dmc->x != lm->lm_tuning.x; \ @@ -740,7 +740,7 @@ dvb_network_create_mux save: if (mm && save) { mm->mm_dmc_origin = origin; - mm->mm_dmc_origin_expire = dispatch_clock + 3600 * 24; /* one day */ + mm->mm_dmc_origin_expire = mdispatch_clock + mono4sec(3600 * 24); /* one day */ idnode_changed(&mm->mm_id); } noop: diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index 08845d5d8..f5798dbca 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -89,7 +89,7 @@ mpegts_network_scan_timer_cb ( void *p ) /* Re-arm timer. Really this is just a safety measure as we'd normally * expect the timer to be forcefully triggered on finish of a mux scan */ - gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 120); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, mono4sec(120)); } /****************************************************************************** @@ -111,7 +111,7 @@ mpegts_network_scan_mux_done0 TAILQ_REMOVE(&mn->mn_scan_pend, mm, mm_scan_link); TAILQ_INSERT_SORTED_R(&mn->mn_scan_pend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp); - gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 10); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, mono4sec(10)); weight = 0; } else { mpegts_network_scan_queue_del(mm); @@ -200,8 +200,8 @@ mpegts_network_scan_queue_del ( mpegts_mux_t *mm ) tvhdebug("mpegts", "%s - removing mux %s from scan queue", buf2, buf); mm->mm_scan_state = MM_SCAN_STATE_IDLE; mm->mm_scan_weight = 0; - gtimer_disarm(&mm->mm_scan_timeout); - gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); + mtimer_disarm(&mm->mm_scan_timeout); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); mpegts_network_scan_notify(mm); } @@ -245,7 +245,7 @@ mpegts_network_scan_queue_add mm->mm_scan_flags = SUBSCRIPTION_IDLESCAN; TAILQ_INSERT_SORTED_R(&mn->mn_scan_pend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp); - gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, delay); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, mono4sec(delay)); mpegts_network_scan_notify(mm); } diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 2fc68f359..249e8a075 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -709,6 +709,7 @@ mpegts_service_create0 { int r; char buf[256]; + time_t dispatch_clock = gdispatch_clock; /* defaults for older version */ s->s_dvb_created = dispatch_clock; @@ -723,8 +724,8 @@ mpegts_service_create0 if (sid) s->s_dvb_service_id = sid; if (pmt_pid) s->s_pmt_pid = pmt_pid; } else { - if (s->s_dvb_last_seen > dispatch_clock) /* sanity check */ - s->s_dvb_last_seen = dispatch_clock; + if (s->s_dvb_last_seen > gdispatch_clock) /* sanity check */ + s->s_dvb_last_seen = gdispatch_clock; } s->s_dvb_mux = mm; if ((r = dvb_servicetype_lookup(s->s_dvb_servicetype)) != -1) @@ -787,8 +788,8 @@ mpegts_service_find if (save) *save = 1; } if (create) { - if ((save && *save) || s->s_dvb_last_seen + 3600 < dispatch_clock) { - s->s_dvb_last_seen = dispatch_clock; + if ((save && *save) || s->s_dvb_last_seen + 3600 < gdispatch_clock) { + s->s_dvb_last_seen = gdispatch_clock; if (save) *save = 1; } } @@ -799,7 +800,7 @@ mpegts_service_find /* Create */ if (create) { s = mm->mm_network->mn_create_service(mm, sid, pmt_pid); - s->s_dvb_created = s->s_dvb_last_seen = dispatch_clock; + s->s_dvb_created = s->s_dvb_last_seen = gdispatch_clock; if (save) *save = 1; } diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index af66fe424..9fa53e27d 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -719,7 +719,7 @@ satip_device_destroy( satip_device_t *sd ) lock_assert(&global_lock); - gtimer_disarm(&sd->sd_destroy_timer); + mtimer_disarm(&sd->sd_destroy_timer); idnode_save_check(&sd->th_id, 1); @@ -764,7 +764,7 @@ satip_device_destroy_cb( void *aux ) void satip_device_destroy_later( satip_device_t *sd, int after ) { - gtimer_arm_ms(&sd->sd_destroy_timer, satip_device_destroy_cb, sd, after); + mtimer_arm_rel(&sd->sd_destroy_timer, satip_device_destroy_cb, sd, mono4ms(after)); } /* @@ -782,7 +782,7 @@ typedef struct satip_discovery { char *deviceid; url_t url; http_client_t *http_client; - time_t http_start; + int64_t http_start; } satip_discovery_t; TAILQ_HEAD(satip_discovery_queue, satip_discovery); @@ -791,10 +791,10 @@ static int satip_enabled; static int satip_discoveries_count; static struct satip_discovery_queue satip_discoveries; static upnp_service_t *satip_discovery_service; -static gtimer_t satip_discovery_timer; -static gtimer_t satip_discovery_static_timer; -static gtimer_t satip_discovery_timerq; -static gtimer_t satip_discovery_msearch_timer; +static mtimer_t satip_discovery_timer; +static mtimer_t satip_discovery_static_timer; +static mtimer_t satip_discovery_timerq; +static mtimer_t satip_discovery_msearch_timer; static str_list_t *satip_static_clients; static void @@ -1006,7 +1006,7 @@ satip_discovery_timerq_cb(void *aux) d = next; next = TAILQ_NEXT(d, disc_link); if (d->http_client) { - if (dispatch_clock - d->http_start > 4) + if (mdispatch_clock - d->http_start > mono4sec(4)) satip_discovery_destroy(d, 1); continue; } @@ -1016,7 +1016,7 @@ satip_discovery_timerq_cb(void *aux) if (d->http_client == NULL) satip_discovery_destroy(d, 1); else { - d->http_start = dispatch_clock; + d->http_start = mdispatch_clock; 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); @@ -1025,7 +1025,7 @@ satip_discovery_timerq_cb(void *aux) } } if (TAILQ_FIRST(&satip_discoveries)) - gtimer_arm(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 5); + mtimer_arm_rel(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, mono4sec(5)); } static void @@ -1134,7 +1134,7 @@ satip_discovery_service_received if (!satip_discovery_find(d) && !satip_device_find(d->uuid)) { TAILQ_INSERT_TAIL(&satip_discoveries, d, disc_link); satip_discoveries_count++; - gtimer_arm_ms(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 250); + mtimer_arm_rel(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, mono4ms(250)); i = 0; } pthread_mutex_unlock(&global_lock); @@ -1148,7 +1148,7 @@ add_uuid: /* if new uuid was discovered, retrigger MSEARCH */ pthread_mutex_lock(&global_lock); if (!satip_device_find(uuid)) - gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 5); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, NULL, mono4sec(5)); pthread_mutex_unlock(&global_lock); } @@ -1210,8 +1210,8 @@ ST: urn:ses-com:device:SatIPServer:1\r\n" upnp_send(&q, NULL, 0, 0); htsbuf_queue_flush(&q); - gtimer_arm_ms(&satip_discovery_msearch_timer, satip_discovery_send_msearch, - (void *)(intptr_t)(attempt + 1), attempt * 11); + mtimer_arm_rel(&satip_discovery_msearch_timer, satip_discovery_send_msearch, + (void *)(intptr_t)(attempt + 1), mono4ms(attempt * 11)); #undef MSG } @@ -1224,7 +1224,7 @@ satip_discovery_static_timer_cb(void *aux) return; for (i = 0; i < satip_static_clients->num; i++) satip_discovery_static(satip_static_clients->str[i]); - gtimer_arm(&satip_discovery_static_timer, satip_discovery_static_timer_cb, NULL, 3600); + mtimer_arm_rel(&satip_discovery_static_timer, satip_discovery_static_timer_cb, NULL, mono4sec(3600)); } static void @@ -1233,7 +1233,8 @@ satip_discovery_timer_cb(void *aux) if (!tvheadend_running) return; if (!upnp_running) { - gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 1); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, + NULL, mono4sec(1)); return; } if (satip_discovery_service == NULL) { @@ -1245,7 +1246,8 @@ satip_discovery_timer_cb(void *aux) } if (satip_discovery_service) satip_discovery_send_msearch((void *)1); - gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 3600); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, + NULL, mono4sec(3600)); } void @@ -1253,8 +1255,10 @@ satip_device_discovery_start( void ) { if (!satip_enabled) return; - gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 1); - gtimer_arm(&satip_discovery_static_timer, satip_discovery_static_timer_cb, NULL, 1); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, + NULL, mono4sec(1)); + mtimer_arm_rel(&satip_discovery_static_timer, satip_discovery_static_timer_cb, + NULL, mono4sec(1)); } /* diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 832ed2189..0bfec3289 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -86,7 +86,8 @@ satip_frontend_signal_cb( void *aux ) streaming_pad_deliver(&svc->s_streaming_pad, streaming_msg_clone(&sm)); pthread_mutex_unlock(&svc->s_stream_mutex); } - gtimer_arm_ms(&lfe->sf_monitor_timer, satip_frontend_signal_cb, lfe, 250); + mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, + lfe, mono4ms(250)); } /* ************************************************************************** @@ -525,7 +526,7 @@ satip_frontend_stop_mux mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2)); tvhdebug("satip", "%s - stopping %s", buf1, buf2); - gtimer_disarm(&lfe->sf_monitor_timer); + mtimer_disarm(&lfe->sf_monitor_timer); /* Stop tune */ tvh_write(lfe->sf_dvr_pipe.wr, "", 1); @@ -591,7 +592,8 @@ satip_frontend_start_mux /* notify thread that we are ready */ tvh_write(lfe->sf_dvr_pipe.wr, "s", 1); - gtimer_arm_ms(&lfe->sf_monitor_timer, satip_frontend_signal_cb, lfe, 50); + mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, + lfe, mono4ms(50)); return 0; } @@ -1121,7 +1123,7 @@ wrdata: } if (lfe->sf_sbuf.sb_ptr > 64 * 1024 || - lfe->sf_last_data_tstamp != dispatch_clock) { + lfe->sf_last_data_tstamp + mono4sec(1) <= mdispatch_clock) { pthread_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) { mmi = lfe->sf_req->sf_mmi; @@ -1130,7 +1132,7 @@ wrdata: &lfe->sf_sbuf, 0, NULL); } pthread_mutex_unlock(&lfe->sf_dvr_lock); - lfe->sf_last_data_tstamp = dispatch_clock; + lfe->sf_last_data_tstamp = mdispatch_clock; } } else if (b[1] == 1) { @@ -1218,14 +1220,14 @@ new_tune: lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); lfe->sf_display_name = buf; - u64_2 = getmonoclock(); + u64_2 = getfastmonoclock(); while (!start) { nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 50 : -1); if (!tvheadend_running) { exit_flag = 1; goto done; } - if (rtsp && getmonoclock() - u64_2 > 50000) /* 50ms */ + if (rtsp && getfastmonoclock() - u64_2 > 50000) /* 50ms */ satip_frontend_close_rtsp(lfe, buf, efd, &rtsp); if (nfds <= 0) continue; @@ -1335,7 +1337,7 @@ new_tune: tc = 1; while (i) { - u64_2 = (getmonoclock() - u64) / 1000; + u64_2 = (getfastmonoclock() - u64) / 1000; if (u64_2 >= (uint64_t)i) break; r = (uint64_t)i - u64_2; @@ -1384,7 +1386,7 @@ new_tune: } pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex); - lfe_master->sf_last_tune = getmonoclock(); + lfe_master->sf_last_tune = getfastmonoclock(); pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex); i = 0; @@ -1605,7 +1607,7 @@ new_tune: } /* We need to keep the session alive */ - if (rtsp->hc_ping_time + rtsp->hc_rtp_timeout / 2 < dispatch_clock && + if (rtsp->hc_ping_time + mono4sec(rtsp->hc_rtp_timeout / 2) < mdispatch_clock && rtsp->hc_cmd == HTTP_CMD_NONE) { rtsp_options(rtsp); reply = 1; @@ -1735,7 +1737,7 @@ done: if (lfe->sf_teardown_delay && lfe_master) { pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex); - lfe->sf_last_tune = lfe_master->sf_last_tune = getmonoclock(); + lfe->sf_last_tune = lfe_master->sf_last_tune = getfastmonoclock(); pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex); } @@ -2019,7 +2021,7 @@ satip_frontend_delete ( satip_frontend_t *lfe ) } /* Stop timer */ - gtimer_disarm(&lfe->sf_monitor_timer); + mtimer_disarm(&lfe->sf_monitor_timer); /* Remove from adapter */ TAILQ_REMOVE(&lfe->sf_device->sd_frontends, lfe, sf_link); diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 23ec7977a..99c36ade1 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -62,7 +62,7 @@ struct satip_device { tvh_hardware_t; - gtimer_t sd_destroy_timer; + mtimer_t sd_destroy_timer; int sd_inload; int sd_nosave; @@ -146,7 +146,7 @@ struct satip_frontend int sf_atsc_c; int sf_position; signal_state_t sf_status; - gtimer_t sf_monitor_timer; + mtimer_t sf_monitor_timer; uint64_t sf_last_tune; satip_tune_req_t *sf_req; satip_tune_req_t *sf_req_thread; diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 56fcdfb31..f5dbe2904 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -73,12 +73,10 @@ ts_recv_packet0 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 + 1 < dispatch_clock && + if (t->s_start_time + mono4sec(1) < mdispatch_clock && tvhlog_limit(&st->es_cc_log, 10)) tvhwarn("TS", "%s Continuity counter error (total %zi)", service_component_nicename(st), st->es_cc_log.count); - avgstat_add(&t->s_cc_errors, 1, dispatch_clock); - avgstat_add(&st->es_cc_errors, 1, dispatch_clock); if (!error) errors++; error |= 2; @@ -143,12 +141,10 @@ ts_recv_skipped0 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 + 1 < dispatch_clock && + if (t->s_start_time + mono4sec(1) < mdispatch_clock && tvhlog_limit(&st->es_cc_log, 10)) tvhwarn("TS", "%s Continuity counter error (total %zi)", service_component_nicename(st), st->es_cc_log.count); - avgstat_add(&t->s_cc_errors, 1, dispatch_clock); - avgstat_add(&st->es_cc_errors, 1, dispatch_clock); } st->es_cc = (cc + 1) & 0xf; } @@ -222,8 +218,6 @@ ts_recv_packet1 if(!error) service_set_streaming_status_flags((service_t*)t, TSS_INPUT_SERVICE); - avgstat_add(&t->s_rate, len, dispatch_clock); - if(!t->s_scrambled_pass && ((tsb[3] & 0xc0) || (t->s_scrambled_seen && st && st->es_type != SCT_CA))) { @@ -331,7 +325,7 @@ ts_flush(mpegts_service_t *t, sbuf_t *sb) streaming_message_t sm; pktbuf_t *pb; - t->s_tsbuf_last = dispatch_clock; + t->s_tsbuf_last = mdispatch_clock; pb = pktbuf_alloc(sb->sb_data, sb->sb_ptr); pb->pb_err = sb->sb_err; @@ -362,7 +356,8 @@ ts_remux(mpegts_service_t *t, const uint8_t *src, int len, int errors) sbuf_append(sb, src, len); sb->sb_err += errors; - if(dispatch_clock == t->s_tsbuf_last && sb->sb_ptr < TS_REMUX_BUFSIZE) + if(sec4mono(mdispatch_clock) == sec4mono(t->s_tsbuf_last) && + sb->sb_ptr < TS_REMUX_BUFSIZE) return; ts_flush(t, sb); @@ -384,7 +379,8 @@ ts_skip(mpegts_service_t *t, const uint8_t *src, int len) sb->sb_err += len / 188; - if(dispatch_clock == t->s_tsbuf_last && sb->sb_err < (TS_REMUX_BUFSIZE / 188)) + if(sec4mono(mdispatch_clock) == sec4mono(t->s_tsbuf_last) && + sb->sb_err < (TS_REMUX_BUFSIZE / 188)) return; ts_flush(t, sb); diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index 6cd2c4c3f..c2b7c4836 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -165,7 +165,7 @@ tsfile_input_thread ( void *aux ) } pcr_last = pcr.pcr_first; #if PLATFORM_LINUX - pcr_last_realtime = getmonoclock(); + pcr_last_realtime = getfastmonoclock(); #endif } } diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c index 49f88dfaf..fdec56d6d 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c @@ -379,7 +379,7 @@ tvhdhomerun_device_discovery_thread( void *aux ) if (tvheadend_running) { brk = tvh_cond_timedwait(&tvhdhomerun_discovery_cond, &tvhdhomerun_discovery_lock, - getmonoclock() + 15 * MONOCLOCK_RESOLUTION); + mdispatch_clock + mono4sec(15)); brk = !ERRNO_AGAIN(brk) && brk != ETIMEDOUT; } pthread_mutex_unlock(&tvhdhomerun_discovery_lock); @@ -439,7 +439,7 @@ tvhdhomerun_device_destroy( tvhdhomerun_device_t *hd ) lock_assert(&global_lock); - gtimer_disarm(&hd->hd_destroy_timer); + mtimer_disarm(&hd->hd_destroy_timer); idnode_save_check(&hd->th_id, 1); diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index e149edd95..fb308df76 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -219,7 +219,7 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) streaming_message_t sm; signal_status_t sigstat; service_t *svc; - int res; + int res, e; struct hdhomerun_tuner_status_t tuner_status; char *tuner_status_str; @@ -228,7 +228,8 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) if (!mmi || !hfe->hf_ready) return; /* re-arm */ - gtimer_arm(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 1); + mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, + hfe, mono4sec(1)); /* Get current status */ pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex); @@ -255,7 +256,11 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) tvh_pipe(O_NONBLOCK, &hfe->hf_input_thread_pipe); pthread_mutex_lock(&hfe->hf_input_thread_mutex); tvhthread_create(&hfe->hf_input_thread, NULL, tvhdhomerun_frontend_input_thread, hfe, "hdhm-front"); - tvh_cond_wait(&hfe->hf_input_thread_cond, &hfe->hf_input_thread_mutex); + do { + e = tvh_cond_wait(&hfe->hf_input_thread_cond, &hfe->hf_input_thread_mutex); + if (e == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(e)); pthread_mutex_unlock(&hfe->hf_input_thread_mutex); /* install table handlers */ @@ -263,7 +268,7 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_delsys); } else { // quick re-arm the timer to wait for signal lock - gtimer_arm_ms(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 50); + mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, mono4ms(50)); } } @@ -415,7 +420,7 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins hfe->hf_status = SIGNAL_NONE; /* start the monitoring */ - gtimer_arm_ms(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 50); + mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, mono4ms(50)); hfe->hf_ready = 1; return 0; @@ -472,7 +477,7 @@ tvhdhomerun_frontend_stop_mux hfe->hf_status = 0; hfe->hf_ready = 0; - gtimer_arm(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 2); + mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, mono4sec(2)); } static void tvhdhomerun_frontend_update_pids( mpegts_input_t *mi, mpegts_mux_t *mm ) @@ -640,7 +645,7 @@ tvhdhomerun_frontend_delete ( tvhdhomerun_frontend_t *hfe ) { lock_assert(&global_lock); - gtimer_disarm(&hfe->hf_monitor_timer); + mtimer_disarm(&hfe->hf_monitor_timer); hdhomerun_device_tuner_lockkey_release(hfe->hf_hdhomerun_tuner); hdhomerun_device_destroy(hfe->hf_hdhomerun_tuner); diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h index 58904af52..a65a18cb4 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h @@ -45,7 +45,7 @@ struct tvhdhomerun_device { tvh_hardware_t; - gtimer_t hd_destroy_timer; + mtimer_t hd_destroy_timer; /* * Adapter info @@ -107,14 +107,14 @@ struct tvhdhomerun_frontend uint8_t hf_input_thread_terminating; // Used for terminating the input_thread. // Global lock for the libhdhomerun library since it seems to have some threading-issues. - pthread_mutex_t hf_hdhomerun_device_mutex; + pthread_mutex_t hf_hdhomerun_device_mutex; /* * Reception */ char hf_pid_filter_buf[1024]; - gtimer_t hf_monitor_timer; + mtimer_t hf_monitor_timer; mpegts_mux_instance_t *hf_mmi; diff --git a/src/main.c b/src/main.c index 641736214..b40dccb58 100644 --- a/src/main.c +++ b/src/main.c @@ -173,6 +173,10 @@ pthread_mutex_t atomic_lock; /* * Locals */ +static LIST_HEAD(, mtimer) mtimers; +static tvh_cond_t mtimer_cond; +static int64_t mtimer_periodic; +static pthread_t mtimer_tid; static LIST_HEAD(, gtimer) gtimers; static pthread_cond_t gtimer_cond; static TAILQ_HEAD(, tasklet) tasklets; @@ -226,60 +230,52 @@ get_user_groups (const struct passwd *pw, gid_t* glist, size_t gmax) /** * */ + +#define safecmp(a, b) ((a) > (b) ? 1 : ((a) < (b) ? -1 : 0)) + static int -gtimercmp(gtimer_t *a, gtimer_t *b) +mtimercmp(mtimer_t *a, mtimer_t *b) { - if(a->gti_expire.tv_sec < b->gti_expire.tv_sec) - return -1; - if(a->gti_expire.tv_sec > b->gti_expire.tv_sec) - return 1; - if(a->gti_expire.tv_nsec < b->gti_expire.tv_nsec) - return -1; - if(a->gti_expire.tv_nsec > b->gti_expire.tv_nsec) - return 1; - return 0; + return safecmp(a->mti_expire, b->mti_expire); } /** * */ void -GTIMER_FCN(gtimer_arm_abs2) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, struct timespec *when) +GTIMER_FCN(mtimer_arm_abs) + (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when) { lock_assert(&global_lock); - if (gti->gti_callback != NULL) - LIST_REMOVE(gti, gti_link); + if (mti->mti_callback != NULL) + LIST_REMOVE(mti, mti_link); - gti->gti_callback = callback; - gti->gti_opaque = opaque; - gti->gti_expire = *when; + mti->mti_callback = callback; + mti->mti_opaque = opaque; + mti->mti_expire = when; #if ENABLE_GTIMER_CHECK - gti->gti_id = id; - gti->gti_fcn = fcn; + mti->mti_id = id; + mti->mti_fcn = fcn; #endif - LIST_INSERT_SORTED(>imers, gti, gti_link, gtimercmp); + LIST_INSERT_SORTED(&mtimers, mti, mti_link, mtimercmp); - if (LIST_FIRST(>imers) == gti) - pthread_cond_signal(>imer_cond); // force timer re-check + if (LIST_FIRST(&mtimers) == mti) + tvh_cond_signal(&mtimer_cond, 0); // force timer re-check } /** * */ void -GTIMER_FCN(gtimer_arm_abs) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when) +GTIMER_FCN(mtimer_arm_rel) + (GTIMER_TRACEID_ mtimer_t *gti, mti_callback_t *callback, void *opaque, int64_t delta) { - struct timespec ts; - ts.tv_nsec = 0; - ts.tv_sec = when; #if ENABLE_GTIMER_CHECK - GTIMER_FCN(gtimer_arm_abs2)(id, fcn, gti, callback, opaque, &ts); + GTIMER_FCN(mtimer_arm_abs)(id, fcn, gti, callback, opaque, mdispatch_clock + delta); #else - gtimer_arm_abs2(gti, callback, opaque, &ts); + mtimer_arm_abs(gti, callback, opaque, mdispatch_clock + delta); #endif } @@ -287,32 +283,60 @@ GTIMER_FCN(gtimer_arm_abs) * */ void -GTIMER_FCN(gtimer_arm) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, int delta) +mtimer_disarm(mtimer_t *mti) +{ + if(mti->mti_callback) { + LIST_REMOVE(mti, mti_link); + mti->mti_callback = NULL; + } +} + +/** + * + */ +static int +gtimercmp(gtimer_t *a, gtimer_t *b) +{ + return safecmp(a->gti_expire, b->gti_expire); +} + +/** + * + */ +void +GTIMER_FCN(gtimer_arm_absn) + (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when) { + lock_assert(&global_lock); + + if (gti->gti_callback != NULL) + LIST_REMOVE(gti, gti_link); + + gti->gti_callback = callback; + gti->gti_opaque = opaque; + gti->gti_expire = when; #if ENABLE_GTIMER_CHECK - GTIMER_FCN(gtimer_arm_abs)(id, fcn, gti, callback, opaque, dispatch_clock + delta); -#else - gtimer_arm_abs(gti, callback, opaque, dispatch_clock + delta); + gti->gti_id = id; + gti->gti_fcn = fcn; #endif + + LIST_INSERT_SORTED(>imers, gti, gti_link, gtimercmp); + + if (LIST_FIRST(>imers) == gti) + pthread_cond_signal(>imer_cond); // force timer re-check } /** * */ void -GTIMER_FCN(gtimer_arm_ms) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, long delta_ms ) +GTIMER_FCN(gtimer_arm_rel) + (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t delta) { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_nsec += (1000000 * delta_ms); - ts.tv_sec += (ts.tv_nsec / 1000000000); - ts.tv_nsec %= 1000000000; #if ENABLE_GTIMER_CHECK - GTIMER_FCN(gtimer_arm_abs2)(id, fcn, gti, callback, opaque, &ts); + GTIMER_FCN(gtimer_arm_absn)(id, fcn, gti, callback, opaque, gdispatch_clock + delta); #else - gtimer_arm_abs2(gti, callback, opaque, &ts); + gtimer_arm_absn(gti, callback, opaque, gdispatch_clock + delta); #endif } @@ -490,20 +514,85 @@ show_usage /** * */ -time_t -dispatch_clock_update(struct timespec *ts) +int64_t +mdispatch_clock_update(void) { - struct timespec ts1; - if (ts == NULL) - ts = &ts1; - clock_gettime(CLOCK_REALTIME, ts); - - /* 1sec stuff */ - if (ts->tv_sec > dispatch_clock) { - dispatch_clock = ts->tv_sec; + int64_t mono = getmonoclock(); + + if (mono > mtimer_periodic) { + mtimer_periodic = mono + MONOCLOCK_RESOLUTION; comet_flush(); /* Flush idle comet mailboxes */ } - return dispatch_clock; + + return mdispatch_clock = mono; +} + +/** + * + */ +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_running) { + now = mdispatch_clock_update(); + + /* Global monoclock timers */ + pthread_mutex_lock(&global_lock); + + next = now + mono4sec(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 + tvhtrace("mtimer", "%s:%s duration %"PRId64"ns", id, fcn, getmonoclock() - 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; +} + +/** + * + */ +time_t +gdispatch_clock_update(void) +{ + return gdispatch_clock = time(NULL); } /** @@ -514,6 +603,7 @@ mainloop(void) { gtimer_t *gti; gti_callback_t *cb; + time_t now; struct timespec ts; #if ENABLE_GTIMER_CHECK int64_t mtm; @@ -521,8 +611,8 @@ mainloop(void) const char *fcn; #endif - while(tvheadend_running) { - dispatch_clock_update(&ts); + while (tvheadend_running) { + now = gdispatch_clock_update(); /* Global timers */ pthread_mutex_lock(&global_lock); @@ -531,18 +621,18 @@ mainloop(void) // the top of the list with a 0 offset we could loop indefinitely #if 0 - tvhdebug("gtimer", "now %ld.%09ld", ts.tv_sec, ts.tv_nsec); + tvhdebug("gtimer", "now %"PRItime_t, ts.tv_sec); LIST_FOREACH(gti, >imers, gti_link) - tvhdebug("gtimer", " gti %p expire %ld.%08ld", - gti, gti->gti_expire.tv_sec, gti->gti_expire.tv_nsec); + tvhdebug("gtimer", " gti %p expire %"PRItimet, gti, gti->gti_expire.tv_sec); #endif + ts.tv_sec += 3600; + ts.tv_nsec = 0; + while((gti = LIST_FIRST(>imers)) != NULL) { - if ((gti->gti_expire.tv_sec > ts.tv_sec) || - ((gti->gti_expire.tv_sec == ts.tv_sec) && - (gti->gti_expire.tv_nsec > ts.tv_nsec))) { - ts = gti->gti_expire; + if (gti->gti_expire > now) { + ts.tv_sec = gti->gti_expire; break; } @@ -563,12 +653,6 @@ mainloop(void) #endif } - /* Bound wait */ - if ((LIST_FIRST(>imers) == NULL) || (ts.tv_sec > (dispatch_clock + 1))) { - ts.tv_sec = dispatch_clock + 1; - ts.tv_nsec = 0; - } - /* Wait */ pthread_cond_timedwait(>imer_cond, &global_lock, &ts); pthread_mutex_unlock(&global_lock); @@ -608,6 +692,7 @@ main(int argc, char **argv) pthread_mutex_init(&global_lock, NULL); pthread_mutex_init(&tasklet_lock, NULL); pthread_mutex_init(&atomic_lock, NULL); + tvh_cond_init(&mtimer_cond); pthread_cond_init(>imer_cond, NULL); tvh_cond_init(&tasklet_cond); TAILQ_INIT(&tasklets); @@ -617,7 +702,8 @@ main(int argc, char **argv) tvheadend_webroot = NULL; tvheadend_htsp_port = 9982; tvheadend_htsp_port_extra = 0; - time(&dispatch_clock); + mdispatch_clock = getmonoclock(); + time(&gdispatch_clock); /* Command line options */ int opt_help = 0, @@ -982,7 +1068,8 @@ main(int argc, char **argv) /* Initialise clock */ pthread_mutex_lock(&global_lock); - time(&dispatch_clock); + mdispatch_clock = getmonoclock(); + time(&gdispatch_clock); /* Signal handling */ sigfillset(&set); @@ -1111,7 +1198,12 @@ main(int argc, char **argv) if(opt_abort) abort(); + tvhthread_create(&mtimer_tid, NULL, mtimer_thread, NULL, "mtimer"); mainloop(); + pthread_mutex_lock(&global_lock); + tvh_cond_signal(&mtimer_cond, 0); + pthread_mutex_unlock(&global_lock); + pthread_join(mtimer_tid, NULL); #if ENABLE_DBUS_1 tvhftrace("main", dbus_server_done); diff --git a/src/muxer/muxer_mkv.c b/src/muxer/muxer_mkv.c index 3b50dc3ca..3ab11c189 100644 --- a/src/muxer/muxer_mkv.c +++ b/src/muxer/muxer_mkv.c @@ -110,7 +110,7 @@ typedef struct mk_muxer { int64_t cluster_tc; off_t cluster_pos; int cluster_maxsize; - time_t cluster_last_close; + int64_t cluster_last_close; off_t segment_header_pos; @@ -942,7 +942,7 @@ mk_close_cluster(mk_muxer_t *mk) if(mk->cluster != NULL) mk_write_master(mk, 0x1f43b675, mk->cluster); mk->cluster = NULL; - mk->cluster_last_close = dispatch_clock; + mk->cluster_last_close = mdispatch_clock; } @@ -992,12 +992,12 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) if(vkeyframe && mk->cluster && (mk->cluster->hq_size > mk->cluster_maxsize || - mk->cluster_last_close + 1 < dispatch_clock)) + mk->cluster_last_close + mono4sec(1) < mdispatch_clock)) mk_close_cluster(mk); else if(!mk->has_video && mk->cluster && (mk->cluster->hq_size > clusersizemax/40 || - mk->cluster_last_close + 1 < dispatch_clock)) + mk->cluster_last_close + mono4sec(1) < mdispatch_clock)) mk_close_cluster(mk); else if(mk->cluster && mk->cluster->hq_size > clusersizemax) diff --git a/src/parsers/parser_h264.c b/src/parsers/parser_h264.c index e8bf6be5f..cc5936e9d 100644 --- a/src/parsers/parser_h264.c +++ b/src/parsers/parser_h264.c @@ -126,7 +126,7 @@ typedef struct h264_private { h264_sps_t sps[MAX_SPS_COUNT]; h264_pps_t pps[MAX_PPS_COUNT]; - time_t start; + int64_t start; } h264_private_t; @@ -232,7 +232,7 @@ h264_decode_seq_parameter_set(elementary_stream_t *st, bitstream_t *bs) if ((p = st->es_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); - p->start = dispatch_clock; + p->start = mdispatch_clock; } profile_idc = read_bits(bs, 8); @@ -348,7 +348,7 @@ h264_decode_pic_parameter_set(elementary_stream_t *st, bitstream_t *bs) if((p = st->es_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); - p->start = dispatch_clock; + p->start = mdispatch_clock; } pps_id = read_golomb_ue(bs); @@ -427,7 +427,7 @@ h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype, 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 + 4 < dispatch_clock) { + if (d == 0 && st->es_frame_duration < 2 && p->start + mono4sec(4) < mdispatch_clock) { tvhwarn("parser", "H264 stream has not timing information, using 30fps"); d = 3000; /* 90000/30 = 3000 : 30fps */ } diff --git a/src/parsers/parser_teletext.c b/src/parsers/parser_teletext.c index 19af16f1f..a2eea48f8 100644 --- a/src/parsers/parser_teletext.c +++ b/src/parsers/parser_teletext.c @@ -619,7 +619,7 @@ tt_construct_unix_time(uint8_t *buf) int i; struct tm tm; - t = dispatch_clock; + t = gdispatch_clock; localtime_r(&t, &tm); tm.tm_hour = atoi((char *)buf); diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 132753415..42f7420fb 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -1835,8 +1835,6 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) pkt->pkt_aspect_num = st->es_aspect_num; pkt->pkt_aspect_den = st->es_aspect_den; - // avgstat_add(&st->es_rate, pkt->pkt_payloadlen, dispatch_clock); - /** * Input is ok */ diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index 1bfba1147..2db787c47 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -64,7 +64,7 @@ typedef struct tsfix { int tf_hasvideo; int tf_wait_for_video; int64_t tf_tsref; - time_t tf_start_time; + int64_t tf_start_time; struct th_pktref_queue tf_ptsq; struct th_pktref_queue tf_backlog; @@ -419,7 +419,7 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) streaming_msg_free(sm); int64_t diff, diff2, threshold; - if(tfs == NULL || dispatch_clock < tf->tf_start_time) { + if(tfs == NULL || mdispatch_clock < tf->tf_start_time) { pkt_ref_dec(pkt); return; } @@ -573,23 +573,12 @@ tsfix_create(streaming_target_t *output) TAILQ_INIT(&tf->tf_ptsq); tf->tf_output = output; - tf->tf_start_time = dispatch_clock; + tf->tf_start_time = mdispatch_clock; streaming_target_init(&tf->tf_input, tsfix_input, tf, 0); return &tf->tf_input; } -/** - * - */ -void tsfix_set_start_time(streaming_target_t *pad, time_t start) -{ - tsfix_t *tf = (tsfix_t *)pad; - - tf->tf_start_time = start; -} - - /** * */ diff --git a/src/plumbing/tsfix.h b/src/plumbing/tsfix.h index 156284fe8..7e6f7bd0b 100644 --- a/src/plumbing/tsfix.h +++ b/src/plumbing/tsfix.h @@ -23,8 +23,6 @@ streaming_target_t *tsfix_create(streaming_target_t *output); -void tsfix_set_start_time(streaming_target_t *pad, time_t start); - void tsfix_destroy(streaming_target_t *gh); diff --git a/src/satip/rtp.c b/src/satip/rtp.c index 154bf3d0d..9173165de 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -140,7 +140,7 @@ static void satip_rtp_header(satip_rtp_session_t *rtp, struct iovec *v, uint32_t off) { uint8_t *data = v->iov_base; - uint32_t tstamp = dispatch_clock + rtp->seq; + uint32_t tstamp = sec4mono(mdispatch_clock) + rtp->seq; rtp->seq++; diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index b0799b986..05a08c3c7 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -60,7 +60,7 @@ typedef struct session { dvb_mux_conf_t dmc; dvb_mux_conf_t dmc_tuned; mpegts_apids_t pids; - gtimer_t timer; + mtimer_t timer; mpegts_mux_t *mux; int mux_created; profile_chain_t prch; @@ -220,7 +220,7 @@ rtsp_rearm_session_timer(session_t *rs) { if (!rs->shutdown_on_close) { pthread_mutex_lock(&global_lock); - gtimer_arm(&rs->timer, rtsp_session_timer_cb, rs, RTSP_TIMEOUT); + mtimer_arm_rel(&rs->timer, rtsp_session_timer_cb, rs, mono4sec(RTSP_TIMEOUT)); pthread_mutex_unlock(&global_lock); } } @@ -1188,7 +1188,7 @@ error: static void rtsp_describe_header(session_t *rs, htsbuf_queue_t *q) { - unsigned long mono = getmonoclock(); + unsigned long mono = mdispatch_clock; int dvbt, dvbc; htsbuf_append_str(q, "v=0\r\n"); @@ -1567,7 +1567,7 @@ rtsp_close_session(session_t *rs) pthread_mutex_lock(&global_lock); mpegts_pid_reset(&rs->pids); rtsp_clean(rs); - gtimer_disarm(&rs->timer); + mtimer_disarm(&rs->timer); pthread_mutex_unlock(&global_lock); } @@ -1579,7 +1579,7 @@ rtsp_free_session(session_t *rs) { TAILQ_REMOVE(&rtsp_sessions, rs, link); pthread_mutex_lock(&global_lock); - gtimer_disarm(&rs->timer); + mtimer_disarm(&rs->timer); pthread_mutex_unlock(&global_lock); mpegts_pid_done(&rs->pids); free(rs); diff --git a/src/service.c b/src/service.c index 75316c8bb..5887eebbd 100644 --- a/src/service.c +++ b/src/service.c @@ -57,7 +57,7 @@ struct service_queue service_all; struct service_queue service_raw_all; struct service_queue service_raw_remove; -static gtimer_t service_raw_remove_timer; +static mtimer_t service_raw_remove_timer; static void service_class_notify_enabled ( void *obj, const char *lang ) @@ -316,9 +316,6 @@ service_stream_destroy(service_t *t, elementary_stream_t *es) if(t->s_status == SERVICE_RUNNING) stream_clean(es); - avgstat_flush(&es->es_rate); - avgstat_flush(&es->es_cc_errors); - if (t->s_last_es == es) { t->s_last_pid = -1; t->s_last_es = NULL; @@ -344,7 +341,7 @@ service_stop(service_t *t) { elementary_stream_t *st; - gtimer_disarm(&t->s_receive_timer); + mtimer_disarm(&t->s_receive_timer); t->s_stop_feed(t); @@ -648,7 +645,7 @@ service_start(service_t *t, int instance, int weight, int flags, t->s_streaming_live = 0; t->s_scrambled_seen = 0; t->s_scrambled_pass = !!(flags & SUBSCRIPTION_NODESCR); - t->s_start_time = dispatch_clock; + t->s_start_time = mdispatch_clock; pthread_mutex_lock(&t->s_stream_mutex); service_build_filter(t); @@ -680,7 +677,8 @@ service_start(service_t *t, int instance, int weight, int flags, t->s_timeout = timeout; t->s_grace_delay = stimeout; if (stimeout > 0) - gtimer_arm(&t->s_receive_timer, service_data_timeout, t, stimeout); + mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, + mono4sec(stimeout)); return 0; } @@ -875,8 +873,6 @@ service_destroy(service_t *t, int delconf) while((st = TAILQ_FIRST(&t->s_components)) != NULL) service_stream_destroy(t, st); - avgstat_flush(&t->s_rate); - switch (t->s_type) { case STYPE_RAW: TAILQ_REMOVE(&service_raw_all, t, s_all_link); @@ -907,7 +903,7 @@ service_remove_raw(service_t *t) t->s_type = STYPE_RAW_REMOVED; TAILQ_REMOVE(&service_raw_all, t, s_all_link); TAILQ_INSERT_TAIL(&service_raw_remove, t, s_all_link); - gtimer_arm(&service_raw_remove_timer, service_remove_raw_timer_cb, NULL, 0); + mtimer_arm_rel(&service_raw_remove_timer, service_remove_raw_timer_cb, NULL, 0); } void @@ -1082,9 +1078,6 @@ service_stream_create(service_t *t, int pid, st->es_pid = pid; - avgstat_init(&st->es_rate, 10); - avgstat_init(&st->es_cc_errors, 10); - service_stream_make_nicename(t, st); if(t->s_status == SERVICE_RUNNING) { @@ -1143,7 +1136,8 @@ service_data_timeout(void *aux) pthread_mutex_unlock(&t->s_stream_mutex); if (t->s_timeout > 0) - gtimer_arm(&t->s_receive_timer, service_data_timeout, t, t->s_timeout); + mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, + mono4sec(t->s_timeout)); } /** diff --git a/src/service.h b/src/service.h index de13a8607..47ea5cda8 100644 --- a/src/service.h +++ b/src/service.h @@ -82,9 +82,6 @@ typedef struct elementary_stream { int8_t es_cc; /* Last CC */ - avgstat_t es_cc_errors; - avgstat_t es_rate; - int es_peak_presentation_delay; /* Max seen diff. of DTS and PTS */ /* For service stream packet reassembly */ @@ -383,13 +380,13 @@ typedef struct service { * it will check if any packets has been parsed. If not the status * will be set to TRANSPORT_STATUS_NO_INPUT */ - gtimer_t s_receive_timer; + mtimer_t s_receive_timer; /** * Stream start time */ - int s_timeout; - int s_grace_delay; - time_t s_start_time; + int s_timeout; + int s_grace_delay; + int64_t s_start_time; /********************************************************* @@ -451,11 +448,6 @@ typedef struct service { elementary_stream_t *s_audio; #endif - /** - * Average bitrate - */ - avgstat_t s_rate; - /** * Descrambling support */ diff --git a/src/spawn.c b/src/spawn.c index d5cd9fa3f..2cab4c841 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -58,7 +58,7 @@ typedef struct spawn { LIST_ENTRY(spawn) link; pid_t pid; const char *name; - time_t killed; + int64_t killed; } spawn_t; static void spawn_reaper(void); @@ -301,7 +301,7 @@ spawn_reaper(void) /* forced kill for expired PIDs */ pthread_mutex_lock(&spawn_mutex); LIST_FOREACH(s, &spawns, link) - if (s->killed && s->killed < dispatch_clock) { + if (s->killed && s->killed < mdispatch_clock) { /* kill the whole process group */ kill(-(s->pid), SIGKILL); } @@ -326,7 +326,7 @@ spawn_kill(pid_t pid, int sig, int timeout) break; if (s) { if (!s->killed) - s->killed = dispatch_clock_update(NULL) + MINMAX(timeout, 5, 3600); + s->killed = mdispatch_clock_update() + mono4sec(MINMAX(timeout, 5, 3600)); /* kill the whole process group */ r = kill(-pid, sig); if (r < 0) diff --git a/src/subscriptions.c b/src/subscriptions.c index 3f7d22d7f..b1cec282c 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -45,7 +45,7 @@ struct th_subscription_list subscriptions; struct th_subscription_list subscriptions_remove; -static gtimer_t subscription_reschedule_timer; +static mtimer_t subscription_reschedule_timer; static int subscription_postpone; /** @@ -147,7 +147,7 @@ subscription_unlink_service0(th_subscription_t *s, int reason, int stop) LIST_REMOVE(s, ths_service_link); if (stop && (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) - gtimer_arm(&s->ths_remove_timer, subscription_unsubscribe_cb, s, 0); + mtimer_arm_rel(&s->ths_remove_timer, subscription_unsubscribe_cb, s, 0); stop: if(LIST_FIRST(&t->s_subscriptions) == NULL) @@ -285,8 +285,8 @@ subscription_start_instance s->ths_source, s->ths_prch, &s->ths_instances, error, s->ths_weight, s->ths_flags, s->ths_timeout, - dispatch_clock > s->ths_postpone_end ? - 0 : s->ths_postpone_end - dispatch_clock); + mdispatch_clock > s->ths_postpone_end ? + 0 : sec4mono(s->ths_postpone_end - mdispatch_clock)); return s->ths_current_instance = si; } @@ -301,7 +301,7 @@ subscription_reschedule(void) service_t *t; service_instance_t *si; streaming_message_t *sm; - int error, postpone = INT_MAX; + int error, postpone = INT_MAX, postpone2; assert(reenter == 0); reenter = 1; @@ -313,10 +313,11 @@ subscription_reschedule(void) /* Postpone the tuner decision */ /* Leave some time to wakeup tuners through DBus or so */ - if (s->ths_postpone_end > dispatch_clock) { - if (postpone > s->ths_postpone_end - dispatch_clock) - postpone = s->ths_postpone_end - dispatch_clock; - sm = streaming_msg_create_code(SMT_GRACE, (s->ths_postpone_end - dispatch_clock) + 5); + if (s->ths_postpone_end > mdispatch_clock) { + postpone2 = sec4mono(s->ths_postpone_end - mdispatch_clock); + if (postpone > postpone2) + postpone = postpone2; + sm = streaming_msg_create_code(SMT_GRACE, postpone + 5); streaming_target_deliver(s->ths_output, sm); continue; } @@ -353,10 +354,10 @@ subscription_reschedule(void) s->ths_current_instance = si; if(si == NULL) { - if (s->ths_last_error != error || s->ths_last_find + 2 >= dispatch_clock) { + if (s->ths_last_error != error || s->ths_last_find + mono4sec(2) >= mdispatch_clock) { tvhtrace("subscription", "%04X: instance not available, retrying", shortid(s)); if (s->ths_last_error != error) - s->ths_last_find = dispatch_clock; + s->ths_last_find = mdispatch_clock; s->ths_last_error = error; continue; } @@ -390,8 +391,8 @@ subscription_reschedule(void) if (postpone <= 0 || postpone == INT_MAX) postpone = 2; - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, postpone); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, mono4sec(postpone)); reenter = 0; } @@ -413,26 +414,25 @@ static int64_t subscription_set_postpone(void *aux, const char *path, int64_t postpone) { th_subscription_t *s; - time_t now = time(NULL); + time_t now = mdispatch_clock_update(); + int64_t postpone2; if (strcmp(path, "/set")) return -1; /* some limits that make sense */ - if (postpone < 0) - postpone = 0; - if (postpone > 120) - postpone = 120; + postpone = MINMAX(postpone, 0, 120); + postpone2 = mono4sec(postpone); pthread_mutex_lock(&global_lock); if (subscription_postpone != postpone) { subscription_postpone = postpone; - tvhinfo("subscriptions", "postpone set to %d seconds", (int)postpone); + tvhinfo("subscriptions", "postpone set to %"PRId64" seconds", postpone); LIST_FOREACH(s, &subscriptions, ths_global_link) { s->ths_postpone = postpone; - if (s->ths_postpone_end > now && s->ths_postpone_end - now > postpone) - s->ths_postpone_end = now + postpone; + if (s->ths_postpone_end > now && s->ths_postpone_end - now > postpone2) + s->ths_postpone_end = now + postpone2; } - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); } pthread_mutex_unlock(&global_lock); return postpone; @@ -453,8 +453,8 @@ subscription_input_null(void *opaque, streaming_message_t *sm) th_subscription_t *s = opaque; if (sm->sm_type == SMT_STOP && s->ths_state != SUBSCRIPTION_ZOMBIE) { LIST_INSERT_HEAD(&subscriptions_remove, s, ths_remove_link); - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); } streaming_msg_free(sm); @@ -642,14 +642,14 @@ subscription_unsubscribe(th_subscription_t *s, int flags) service_instance_list_clear(&s->ths_instances); - gtimer_disarm(&s->ths_remove_timer); + mtimer_disarm(&s->ths_remove_timer); if ((flags & UNSUBSCRIBE_FINAL) != 0 || (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) subscription_destroy(s); - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); notify_reload("subscriptions"); } @@ -706,7 +706,7 @@ subscription_create s->ths_flags = flags; s->ths_timeout = pro ? pro->pro_timeout : 0; s->ths_postpone = subscription_postpone; - s->ths_postpone_end = dispatch_clock + s->ths_postpone; + s->ths_postpone_end = mdispatch_clock + mono4sec(s->ths_postpone); if (s->ths_prch) s->ths_weight = profile_chain_weight(s->ths_prch, weight); @@ -726,8 +726,8 @@ subscription_create LIST_INSERT_SORTED(&subscriptions, s, ths_global_link, subscription_sort); - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); notify_reload("subscriptions"); return s; @@ -796,8 +796,8 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, subscription_link_service(s, si->si_s); subscription_show_info(s); } else { - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); } return s; } @@ -871,7 +871,7 @@ subscription_create_from_mux(profile_chain_t *prch, * Status monitoring * *************************************************************************/ -static gtimer_t subscription_status_timer; +static mtimer_t subscription_status_timer; /* * Serialize info about subscription @@ -965,8 +965,8 @@ subscription_status_callback ( void *p ) int64_t count = 0; static int64_t old_count = -1; - gtimer_arm(&subscription_status_timer, - subscription_status_callback, NULL, 1); + mtimer_arm_rel(&subscription_status_timer, + subscription_status_callback, NULL, mono4sec(1)); LIST_FOREACH(s, &subscriptions, ths_global_link) { /* Store the difference between total bytes from the last round */ @@ -1008,6 +1008,7 @@ void subscription_done(void) { pthread_mutex_lock(&global_lock); + mtimer_disarm(&subscription_status_timer); /* clear remaining subscriptions */ subscription_reschedule(); pthread_mutex_unlock(&global_lock); @@ -1052,8 +1053,8 @@ subscription_change_weight(th_subscription_t *s, int weight) LIST_INSERT_SORTED(&subscriptions, s, ths_global_link, subscription_sort); - gtimer_arm(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, 0); } /** @@ -1126,7 +1127,7 @@ dummy_callback(void *opauqe, streaming_message_t *sm) streaming_msg_free(sm); } -static gtimer_t dummy_sub_timer; +static mtimer_t dummy_sub_timer; /** * */ @@ -1149,7 +1150,7 @@ subscription_dummy_join(const char *id, int first) th_subscription_t *s; if(first) { - gtimer_arm(&dummy_sub_timer, dummy_retry, strdup(id), 2); + mtimer_arm_rel(&dummy_sub_timer, dummy_retry, strdup(id), mono4sec(2)); return; } @@ -1157,7 +1158,7 @@ subscription_dummy_join(const char *id, int first) tvhlog(LOG_ERR, "subscription", "Unable to dummy join %s, service not found, retrying...", id); - gtimer_arm(&dummy_sub_timer, dummy_retry, strdup(id), 1); + mtimer_arm_rel(&dummy_sub_timer, dummy_retry, strdup(id), mono4sec(1)); return; } diff --git a/src/subscriptions.h b/src/subscriptions.h index 25f171870..510a1a0bf 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -78,7 +78,7 @@ typedef struct th_subscription { int ths_testing_error; - gtimer_t ths_remove_timer; + mtimer_t ths_remove_timer; LIST_ENTRY(th_subscription) ths_channel_link; struct channel *ths_channel; /* May be NULL if channel has been @@ -108,7 +108,7 @@ typedef struct th_subscription { int ths_flags; int ths_timeout; - time_t ths_last_find; + int64_t ths_last_find; int ths_last_error; streaming_message_t *ths_start_message; @@ -127,8 +127,8 @@ typedef struct th_subscription { /** * Postpone */ - int ths_postpone; - time_t ths_postpone_end; + int ths_postpone; + int64_t ths_postpone_end; /* * MPEG-TS mux chain diff --git a/src/tcp.c b/src/tcp.c index 11dd31d73..0235b2462 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -507,7 +507,7 @@ tcp_connection_launch { tcp_server_launch_t *tsl, *res; uint32_t used = 0, used2; - time_t started = dispatch_clock; + int64_t started = mdispatch_clock; int c1, c2; lock_assert(&global_lock); @@ -539,7 +539,7 @@ try_again: c2 = aa->aa_conn_limit_streaming ? used >= aa->aa_conn_limit_streaming : -1; if (c1 && c2) { - if (started + 3 < dispatch_clock) { + if (started + mono4sec(3) < mdispatch_clock) { 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 ?: "", @@ -1112,9 +1112,9 @@ tcp_server_done(void) tvh_pipe_close(&tcp_server_pipe); tvhpoll_destroy(tcp_server_poll); - t = getmonoclock(); + t = getfastmonoclock(); while (LIST_FIRST(&tcp_server_active) != NULL) { - if (getmonoclock() - t > 5000000) + if (t + mono4sec(5) < getfastmonoclock()) tvhtrace("tcp", "tcp server %p active too long", LIST_FIRST(&tcp_server_active)); usleep(20000); } diff --git a/src/timeshift.c b/src/timeshift.c index e85a52002..72387bd37 100644 --- a/src/timeshift.c +++ b/src/timeshift.c @@ -335,10 +335,10 @@ static void timeshift_input goto _exit; } else { if (ts->ref_time == 0) { - ts->ref_time = getmonoclock(); + ts->ref_time = getfastmonoclock(); sm->sm_time = 0; } else { - sm->sm_time = getmonoclock() - ts->ref_time; + sm->sm_time = getfastmonoclock() - ts->ref_time; } } streaming_target_deliver2(&ts->wr_queue.sq_st, sm); diff --git a/src/timeshift/timeshift_filemgr.c b/src/timeshift/timeshift_filemgr.c index 6613168a1..57d4b9964 100644 --- a/src/timeshift/timeshift_filemgr.c +++ b/src/timeshift/timeshift_filemgr.c @@ -239,7 +239,7 @@ static timeshift_file_t * timeshift_filemgr_file_init timeshift_file_t *tsf; tsf = calloc(1, sizeof(timeshift_file_t)); - tsf->time = start_time / (MONOCLOCK_RESOLUTION * TIMESHIFT_FILE_PERIOD); + tsf->time = sec4mono(start_time) / TIMESHIFT_FILE_PERIOD; tsf->last = start_time; tsf->wfd = -1; tsf->rfd = -1; @@ -272,7 +272,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) /* Store to file */ tsf_tl = TAILQ_LAST(&ts->files, timeshift_file_list); - time = start_time / (MONOCLOCK_RESOLUTION * TIMESHIFT_FILE_PERIOD); + time = sec4mono(start_time) / TIMESHIFT_FILE_PERIOD; if (!tsf_tl || tsf_tl->time < time || (tsf_tl->ram && tsf_tl->woff >= timeshift_conf.ram_segment_size)) { tsf_hd = TAILQ_FIRST(&ts->files); diff --git a/src/timeshift/timeshift_reader.c b/src/timeshift/timeshift_reader.c index 3f512d700..31ee524e5 100644 --- a/src/timeshift/timeshift_reader.c +++ b/src/timeshift/timeshift_reader.c @@ -281,7 +281,7 @@ static int _timeshift_skip { timeshift_index_iframe_t *tsi = seek->frame; timeshift_file_t *tsf = seek->file, *tsf_last; - int64_t sec = req_time / (MONOCLOCK_RESOLUTION * TIMESHIFT_FILE_PERIOD); + int64_t sec = sec4mono(req_time) / TIMESHIFT_FILE_PERIOD; int back = (req_time < cur_time) ? 1 : 0; int end = 0; @@ -561,7 +561,7 @@ void *timeshift_reader ( void *p ) wait = -1; end = 0; skip = NULL; - mono_now = getmonoclock(); + mono_now = getfastmonoclock(); /* Control */ pthread_mutex_lock(&ts->state_mutex); @@ -773,7 +773,7 @@ void *timeshift_reader ( void *p ) /* Done */ if (!run || !seek->file || ((ts->state != TS_PLAY && !skip))) { - if (mono_now >= (mono_last_status + MONOCLOCK_RESOLUTION)) { + if (mono_now >= (mono_last_status + mono4sec(1))) { timeshift_status(ts, last_time); mono_last_status = mono_now; } @@ -865,7 +865,7 @@ void *timeshift_reader ( void *p ) } /* Periodic timeshift status */ - if (mono_now >= (mono_last_status + MONOCLOCK_RESOLUTION)) { + if (mono_now >= (mono_last_status + mono4sec(1))) { timeshift_status(ts, last_time); mono_last_status = mono_now; } diff --git a/src/tvheadend.h b/src/tvheadend.h index 873dc79fa..ffc5d5503 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -47,7 +47,6 @@ #endif #endif #include "queue.h" -#include "avg.h" #include "hts_strtab.h" #include "htsmsg.h" #include "tvhlog.h" @@ -153,7 +152,50 @@ typedef enum { #define PICON_ISVCTYPE 1 /* - * global timer + * timer support functions + */ + +#if ENABLE_GTIMER_CHECK +#define GTIMER_TRACEID_ const char *id, const char *fcn, +#define GTIMER_FCN(n) check_##n +#else +#define GTIMER_TRACEID_ +#define GTIMER_FCN(n) n +#endif + +/* + * global timer - monotonic + */ + +typedef void (mti_callback_t)(void *opaque); + +typedef struct mtimer { + LIST_ENTRY(mtimer) mti_link; + mti_callback_t *mti_callback; + void *mti_opaque; + int64_t mti_expire; +#if ENABLE_GTIMER_CHECK + const char *mti_id; + const char *mti_fcn; +#endif +} mtimer_t; + +void GTIMER_FCN(mtimer_arm_rel) + (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t delta); +void GTIMER_FCN(mtimer_arm_abs) + (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when); + +#if ENABLE_GTIMER_CHECK +#define mtimer_arm_rel(a, b, c, d) GTIMER_FCN(mtimer_arm_rel)(SRCLINEID(), __func__, a, b, c, d) +#define mtimer_arm_abs(a, b, c, d) GTIMER_FCN(mtimer_arm_abs)(SRCLINEID(), __func__, a, b, c, d) +#endif + +void mtimer_disarm(mtimer_t *mti); + + + +/* + * global timer (based on the current system time - time()) */ typedef void (gti_callback_t)(void *opaque); @@ -162,35 +204,21 @@ typedef struct gtimer { LIST_ENTRY(gtimer) gti_link; gti_callback_t *gti_callback; void *gti_opaque; - struct timespec gti_expire; + time_t gti_expire; #if ENABLE_GTIMER_CHECK const char *gti_id; const char *gti_fcn; #endif } gtimer_t; -#if ENABLE_GTIMER_CHECK -#define GTIMER_TRACEID_ const char *id, const char *fcn, -#define GTIMER_FCN(n) check_##n -#else -#define GTIMER_TRACEID_ -#define GTIMER_FCN(n) n -#endif - -void GTIMER_FCN(gtimer_arm) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, int delta); -void GTIMER_FCN(gtimer_arm_ms) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, long delta_ms); -void GTIMER_FCN(gtimer_arm_abs) +void GTIMER_FCN(gtimer_arm_rel) + (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t delta); +void GTIMER_FCN(gtimer_arm_absn) (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when); -void GTIMER_FCN(gtimer_arm_abs2) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, struct timespec *when); #if ENABLE_GTIMER_CHECK -#define gtimer_arm(a, b, c, d) GTIMER_FCN(gtimer_arm)(SRCLINEID(), __func__, a, b, c, d) -#define gtimer_arm_ms(a, b, c, d) GTIMER_FCN(gtimer_arm_ms)(SRCLINEID(), __func__, a, b, c, d) -#define gtimer_arm_abs(a, b, c, d) GTIMER_FCN(gtimer_arm_abs)(SRCLINEID(), __func__, a, b, c, d) -#define gtimer_arm_abs2(a, b, c, d) GTIMER_FCN(gtimer_arm_abs2)(SRCLINEID(), __func__, a, b, c, d) +#define gtimer_arm_rel(a, b, c, d) GTIMER_FCN(gtimer_arm_rel)(SRCLINEID(), __func__, a, b, c, d) +#define gtimer_arm_absn(a, b, c, d) GTIMER_FCN(gtimer_arm_absn)(SRCLINEID(), __func__, a, b, c, d) #endif void gtimer_disarm(gtimer_t *gti); @@ -614,41 +642,9 @@ static inline unsigned int tvh_strhash(const char *s, unsigned int mod) void tvh_str_set(char **strp, const char *src); int tvh_str_update(char **strp, const char *src); -#ifndef CLOCK_MONOTONIC_COARSE -#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC -#endif - -#ifdef PLATFORM_DARWIN -#define CLOCK_MONOTONIC 0 -#define CLOCK_REALTIME 0 - -static inline int clock_gettime(int clk_id, struct timespec* t) { - struct timeval now; - int rv = gettimeofday(&now, NULL); - if (rv) return rv; - t->tv_sec = now.tv_sec; - t->tv_nsec = now.tv_usec * 1000; - return 0; -} -#endif - -#define MONOCLOCK_RESOLUTION 1000000LL /* microseconds */ - -static inline int64_t -getmonoclock(void) -{ - struct timespec tp; - - clock_gettime(CLOCK_MONOTONIC_COARSE, &tp); - - return tp.tv_sec * MONOCLOCK_RESOLUTION + - (tp.tv_nsec / (1000000000LL/MONOCLOCK_RESOLUTION)); -} - int sri_to_rate(int sri); int rate_to_sri(int rate); - extern struct service_list all_transports; extern void scopedunlock(pthread_mutex_t **mtxp); @@ -865,16 +861,4 @@ void tvh_qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void #define PRItime_t "ld" #endif -void time_t_out_of_range_notify(int64_t val); - -static inline time_t time_t_out_of_range(uint64_t val) -{ - time_t r = val; - if ((int64_t)r != val) { - time_t_out_of_range_notify(val); - r = INT32_MAX; - } - return r; -} - #endif /* TVHEADEND_H */ diff --git a/src/tvhlog.c b/src/tvhlog.c index 7831121b4..564afad9b 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -30,7 +30,8 @@ #include "libav.h" #include "webui/webui.h" -time_t dispatch_clock; +int64_t mdispatch_clock; +time_t gdispatch_clock; int tvhlog_run; int tvhlog_level; diff --git a/src/tvhlog.h b/src/tvhlog.h index 8b19bec18..ef5f58729 100644 --- a/src/tvhlog.h +++ b/src/tvhlog.h @@ -30,16 +30,14 @@ #include #include "atomic.h" +#include "clock.h" #include "htsmsg.h" typedef struct { - time_t last; + int64_t last; size_t count; } tvhlog_limit_t; -/* Globals */ -extern time_t dispatch_clock; - /* Config */ extern int tvhlog_level; extern htsmsg_t *tvhlog_debug; @@ -70,8 +68,9 @@ void _tvhlog_hexdump ( const char *file, int line, 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 ) - { time_t t = dispatch_clock; limit->count++; - if (limit->last + delay < t) { limit->last = t; return 1; } + { int64_t t = mdispatch_clock; limit->count++; + if (limit->last + (int64_t)delay * MONOCLOCK_RESOLUTION < t) + { limit->last = t; return 1; } return 0; } @@ -130,8 +129,6 @@ static inline void tvhtrace_no_warnings(const char *fmt, ...) { (void)fmt; } #define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__) #define tvhalert(...) tvhlog(LOG_ALERT, ##__VA_ARGS__) -time_t dispatch_clock_update(struct timespec *ts); - void tvhlog_backtrace_printf(const char *fmt, ...); #endif /* __TVH_LOGGING_H__ */ diff --git a/src/webui/comet.c b/src/webui/comet.c index 0f539b277..3f7ed2191 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -57,7 +57,7 @@ typedef struct comet_mailbox { char *cmb_boxid; /* SHA-1 hash */ char *cmb_lang; /* UI language */ htsmsg_t *cmb_messages; /* A vector */ - time_t cmb_last_used; + int64_t cmb_last_used; LIST_ENTRY(comet_mailbox) cmb_link; int cmb_debug; } comet_mailbox_t; @@ -95,7 +95,7 @@ comet_flush(void) for(cmb = LIST_FIRST(&mailboxes); cmb != NULL; cmb = next) { next = LIST_NEXT(cmb, cmb_link); - if(cmb->cmb_last_used && cmb->cmb_last_used + 60 < dispatch_clock) + if(cmb->cmb_last_used && cmb->cmb_last_used + mono4sec(60) < mdispatch_clock) cmb_destroy(cmb); } pthread_mutex_unlock(&comet_mutex); @@ -131,7 +131,7 @@ comet_mailbox_create(const char *lang) cmb->cmb_boxid = strdup(id); cmb->cmb_lang = lang ? strdup(lang) : NULL; - time(&cmb->cmb_last_used); + cmb->cmb_last_used = mdispatch_clock; mailbox_tally++; LIST_INSERT_HEAD(&mailboxes, cmb, cmb_link); @@ -238,7 +238,8 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) comet_mailbox_t *cmb = NULL; const char *cometid = http_arg_get(&hc->hc_req_args, "boxid"); const char *immediate = http_arg_get(&hc->hc_req_args, "immediate"); - int im = immediate ? atoi(immediate) : 0; + int im = immediate ? atoi(immediate) : 0, e; + int64_t mono; htsmsg_t *m; if(!im) @@ -263,8 +264,12 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) cmb->cmb_last_used = 0; /* Make sure we're not flushed out */ if(!im && cmb->cmb_messages == NULL) { - tvh_cond_timedwait(&comet_cond, &comet_mutex, - getmonoclock() + 10 * MONOCLOCK_RESOLUTION); + mono = mdispatch_clock + mono4sec(10); + do { + e = tvh_cond_timedwait(&comet_cond, &comet_mutex, mono); + if (e == ETIMEDOUT) + break; + } while (ERRNO_AGAIN(e)); if (!comet_running) { pthread_mutex_unlock(&comet_mutex); return 400; @@ -276,7 +281,7 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_msg(m, "messages", cmb->cmb_messages ?: htsmsg_create_list()); cmb->cmb_messages = NULL; - cmb->cmb_last_used = dispatch_clock; + cmb->cmb_last_used = mdispatch_clock; pthread_mutex_unlock(&comet_mutex); diff --git a/src/webui/webui.c b/src/webui/webui.c index fbd4b17f7..f07c3817d 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -311,15 +311,13 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, const char *name, th_subscription_t *s) { streaming_message_t *sm; - int run = 1; - int started = 0; + int run = 1, started = 0; streaming_queue_t *sq = &prch->prch_sq; muxer_t *mux = prch->prch_muxer; - time_t lastpkt; - int ptimeout, grace = 20; + int ptimeout, grace = 20, r; struct timeval tp; streaming_start_t *ss_copy; - int64_t mono; + int64_t lastpkt, mono; if(muxer_open_stream(mux, hc->hc_fd)) run = 0; @@ -331,7 +329,7 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, if (config.dscp >= 0) socket_set_dscp(hc->hc_fd, config.dscp, NULL, 0); - lastpkt = dispatch_clock; + lastpkt = mdispatch_clock; ptimeout = prch->prch_pro ? prch->prch_pro->pro_timeout : 5; if (hc->hc_no_output) { @@ -344,18 +342,22 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, pthread_mutex_lock(&sq->sq_mutex); sm = TAILQ_FIRST(&sq->sq_queue); if(sm == NULL) { - if(tvh_cond_timedwait(&sq->sq_cond, &sq->sq_mutex, - getmonoclock() + 1 * MONOCLOCK_RESOLUTION) == ETIMEDOUT) { - /* Check socket status */ - 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 && dispatch_clock - lastpkt > grace) || - (started && ptimeout > 0 && dispatch_clock - lastpkt > ptimeout)) { - tvhlog(LOG_WARNING, "webui", "Stop streaming %s, timeout waiting for packets", hc->hc_url_orig); - run = 0; + mono = mdispatch_clock + mono4sec(1); + do { + r = tvh_cond_timedwait(&sq->sq_cond, &sq->sq_mutex, mono); + if (r == ETIMEDOUT) { + /* Check socket status */ + 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 > mono4sec(grace)) || + (started && ptimeout > 0 && mdispatch_clock - lastpkt > mono4sec(ptimeout))) { + tvhlog(LOG_WARNING, "webui", "Stop streaming %s, timeout waiting for packets", hc->hc_url_orig); + run = 0; + } + break; } - } + } while (ERRNO_AGAIN(r)); pthread_mutex_unlock(&sq->sq_mutex); continue; } @@ -375,7 +377,7 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, pb = sm->sm_data; subscription_add_bytes_out(s, len = pktbuf_len(pb)); if (len > 0) - lastpkt = dispatch_clock; + lastpkt = mdispatch_clock; muxer_write_pkt(mux, sm->sm_type, sm->sm_data); sm->sm_data = NULL; } @@ -394,8 +396,8 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, if (hc->hc_no_output) { streaming_msg_free(sm); - mono = getmonoclock() + 2000000; - while (getmonoclock() < mono) { + mono = getfastmonoclock() + mono4sec(2); + while (getfastmonoclock() < mono) { if (tcp_socket_dead(hc->hc_fd)) break; usleep(50000); @@ -427,8 +429,8 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, tvhlog(LOG_DEBUG, "webui", "Stop streaming %s, client hung up", hc->hc_url_orig); run = 0; - } else if((!started && dispatch_clock - lastpkt > grace) || - (started && ptimeout > 0 && dispatch_clock - lastpkt > ptimeout)) { + } else if((!started && mdispatch_clock - lastpkt > mono4sec(grace)) || + (started && ptimeout > 0 && mdispatch_clock - lastpkt > mono4sec(ptimeout))) { tvhlog(LOG_WARNING, "webui", "Stop streaming %s, timeout waiting for packets", hc->hc_url_orig); run = 0; } diff --git a/src/wrappers.c b/src/wrappers.c index aa9b788e6..596ad681e 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -78,17 +78,16 @@ tvh_pipe_close(th_pipe_t *p) int tvh_write(int fd, const void *buf, size_t len) { - time_t next = dispatch_clock + 25; + int64_t limit = mdispatch_clock + mono4sec(25); ssize_t c; while (len) { c = write(fd, buf, len); if (c < 0) { if (ERRNO_AGAIN(errno)) { - if (dispatch_clock > next) + if (mdispatch_clock > limit) break; usleep(100); - dispatch_clock_update(NULL); continue; } break; @@ -202,11 +201,11 @@ int tvh_mutex_timedlock ( pthread_mutex_t *mutex, int64_t usec ) { - int64_t finish = getmonoclock() + usec; + int64_t finish = getfastmonoclock() + usec; int retcode; while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) { - if (getmonoclock() >= finish) + if (getfastmonoclock() >= finish) return ETIMEDOUT; usleep(10000);