From 19eb89026cbdf968d15c6e24fec2980975230c6d Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 5 Mar 2016 17:01:33 +0100 Subject: [PATCH] remove usleep/nanosleep calls - use own functions --- src/clock.h | 5 ++ src/config.c | 2 +- src/htsp_server.c | 2 +- src/input/mpegts/iptv/iptv_http.c | 2 +- src/input/mpegts/linuxdvb/linuxdvb_adapter.c | 6 +- src/input/mpegts/linuxdvb/linuxdvb_en50494.c | 8 +-- src/input/mpegts/linuxdvb/linuxdvb_frontend.c | 2 +- src/input/mpegts/linuxdvb/linuxdvb_rotor.c | 4 +- src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 6 +- src/input/mpegts/linuxdvb/linuxdvb_switch.c | 6 +- src/input/mpegts/tsfile/tsfile_input.c | 28 +++------ src/notify.c | 2 +- src/satip/rtp.c | 11 ++-- src/tcp.c | 4 +- src/udp.c | 2 +- src/upnp.c | 2 +- src/webui/comet.c | 2 +- src/webui/webui.c | 2 +- src/wrappers.c | 59 ++++++++++++++++++- 19 files changed, 103 insertions(+), 52 deletions(-) diff --git a/src/clock.h b/src/clock.h index 79d8db096..c2a65d0c4 100644 --- a/src/clock.h +++ b/src/clock.h @@ -105,4 +105,9 @@ static inline time_t time_t_out_of_range(uint64_t val) return r; } +void tvh_safe_usleep(int64_t us); + +int64_t tvh_usleep(int64_t us); +int64_t tvh_usleep_abs(int64_t us); + #endif /* TVHEADEND_CLOCK_H */ diff --git a/src/config.c b/src/config.c index 8e6ff9d21..a81060b46 100644 --- a/src/config.c +++ b/src/config.c @@ -1458,7 +1458,7 @@ dobackup(const char *oldver) code = -ENOENT; } else { while ((code = spawn_reap(pid, errtxt, sizeof(errtxt))) == -EAGAIN) - usleep(20000); + tvh_safe_usleep(20000); if (code == -ECHILD) code = 0; tvhinfo("config", "backup: completed"); diff --git a/src/htsp_server.c b/src/htsp_server.c index c47b50c2d..220e9a77f 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -3093,7 +3093,7 @@ readmsg: pthread_mutex_unlock(&global_lock); /* Classic authentication failed delay */ - usleep(250000); + tvh_safe_usleep(250000); reply = htsmsg_create_map(); htsmsg_add_u32(reply, "noaccess", 1); diff --git a/src/input/mpegts/iptv/iptv_http.c b/src/input/mpegts/iptv/iptv_http.c index 71282ad5b..2bcf8c945 100644 --- a/src/input/mpegts/iptv/iptv_http.c +++ b/src/input/mpegts/iptv/iptv_http.c @@ -84,7 +84,7 @@ iptv_http_safe_global_lock( http_priv_t *hp ) if (r == 0) break; if (r == EBUSY) - usleep(10000); + tvh_safe_usleep(10000); } return 1; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 24e4a31ca..c64840ef8 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -315,7 +315,7 @@ linuxdvb_adapter_add ( const char *path ) if (!i) { for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { if (!access(fe_path, R_OK | W_OK)) break; - usleep(100000); + tvh_safe_usleep(100000); } } if (access(fe_path, R_OK | W_OK)) continue; @@ -323,7 +323,7 @@ linuxdvb_adapter_add ( const char *path ) /* Get frontend info */ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { if ((fd = tvh_open(fe_path, O_RDWR, 0)) >= 0) break; - usleep(100000); + tvh_safe_usleep(100000); } if (fd < 0) { tvhlog(LOG_ERR, "linuxdvb", "unable to open %s", fe_path); @@ -413,7 +413,7 @@ linuxdvb_adapter_add ( const char *path ) /* Get ca info */ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { if ((fd = tvh_open(ca_path, O_RDWR, 0)) >= 0) break; - usleep(100000); + tvh_safe_usleep(100000); } if (fd < 0) { tvhlog(LOG_ERR, "linuxdvb", "unable to open %s", ca_path); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c index e33b2a138..d3501a414 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c @@ -223,7 +223,7 @@ linuxdvb_en50494_tune tvherror("en50494","failed to lock for tuning"); return -1; } - usleep(20000); + tvh_safe_usleep(20000); } /* setup en50494 switch */ @@ -234,7 +234,7 @@ linuxdvb_en50494_tune uint8_t rnd; uuid_random(&rnd, 1); int ms = ((int)rnd)%50 + 68; - usleep(ms*1000); + tvh_safe_usleep(ms*1000); } /* use 18V */ @@ -243,7 +243,7 @@ linuxdvb_en50494_tune tvherror("en50494", "error setting lnb voltage to 18V"); break; } - usleep(15000); /* standard: 4ms < x < 22ms */ + tvh_safe_usleep(15000); /* standard: 4ms < x < 22ms */ /* send tune command (with/without pin) */ tvhdebug("en50494", @@ -269,7 +269,7 @@ linuxdvb_en50494_tune tvherror("en50494", "error send tune command"); break; } - usleep(50000); /* standard: 2ms < x < 60ms */ + tvh_safe_usleep(50000); /* standard: 2ms < x < 60ms */ /* return to 13V */ ret = linuxdvb_diseqc_set_volt(lsp, 0); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 1437e9271..4fa76389a 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -1756,7 +1756,7 @@ linuxdvb_frontend_tune1 rep = lfe->lfe_tune_repeats > 0 ? lfe->lfe_tune_repeats : 0; for (i = 0; i <= rep; i++) { if (i > 0) - usleep(15000); + tvh_safe_usleep(15000); r = linuxdvb_frontend_tune0(lfe, mmi, freq); if (r) break; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index f4844323d..c95d41ff3 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -376,7 +376,7 @@ linuxdvb_rotor_gotox_tune tvherror("diseqc", "failed to set GOTOX pos %d", lr->lr_position); return -1; } - usleep(MINMAX(lr->lr_cmd_time, 10, 100) * 1000); + tvh_safe_usleep(MINMAX(lr->lr_cmd_time, 10, 100) * 1000); } tvhdebug("diseqc", "rotor GOTOX pos %d sent", lr->lr_position); @@ -412,7 +412,7 @@ linuxdvb_rotor_usals_tune tvherror("diseqc", "failed to send USALS command"); return -1; } - usleep(MINMAX(lr->lr_cmd_time, 10, 100) * 1000); + tvh_safe_usleep(MINMAX(lr->lr_cmd_time, 10, 100) * 1000); } return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 53f95503a..0d0b4d84d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -758,7 +758,7 @@ linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol ) /* the linuxdvb_diseqc_set_volt() fcn already sleeps for 15ms */ if (delay > 15) { tvhtrace("diseqc", "initial sleep %dms", delay); - usleep((delay-15)*1000); + tvh_safe_usleep((delay-15)*1000); } return 0; } @@ -852,7 +852,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) return -1; } ls->ls_last_tone_off = band + 1; - usleep(20000); // Allow LNB to settle before tuning + tvh_safe_usleep(20000); // Allow LNB to settle before tuning } } @@ -1576,7 +1576,7 @@ linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int vol ) return -1; } if (vol >= 0) - usleep(15000); + tvh_safe_usleep(15000); ls->ls_last_vol = vol ? (vol < 0 ? 0 : 2) : 1; return 0; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index a2905803e..11a368f61 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -196,14 +196,14 @@ linuxdvb_switch_tune if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, 0xF0 | ls->ls_uncommitted)) return -1; - usleep(slp); + tvh_safe_usleep(slp); } /* Committed */ if (ls->ls_committed >= 0) { if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x38, 1, com)) return -1; - usleep(slp); + tvh_safe_usleep(slp); } if (!ls->ls_uncommitted_first) { @@ -212,7 +212,7 @@ linuxdvb_switch_tune if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, 0xF0 | ls->ls_uncommitted)) return -1; - usleep(slp); + tvh_safe_usleep(slp); } } diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index c2b7c4836..34a0078ba 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -46,9 +46,7 @@ tsfile_input_thread ( void *aux ) sbuf_t buf; mpegts_pcr_t pcr; int64_t pcr_last = PTS_UNSET; -#if PLATFORM_LINUX - int64_t pcr_last_realtime = 0; -#endif + int64_t pcr_last_mono = 0; tsfile_input_t *mi = aux; mpegts_mux_instance_t *mmi; tsfile_mux_instance_t *tmi; @@ -90,6 +88,8 @@ tsfile_input_thread ( void *aux ) len = 0; tvhtrace("tsfile", "adapter %d file size %jd rem %zu", mi->mi_instance, (intmax_t)st.st_size, rem); + + pcr_last_mono = getfastmonoclock(); /* Process input */ while (1) { @@ -141,8 +141,7 @@ tsfile_input_thread ( void *aux ) /* Delay */ if (pcr.pcr_first != PTS_UNSET) { if (pcr_last != PTS_UNSET) { - struct timespec slp; - int64_t delta; + int64_t delta, r; delta = pcr.pcr_first - pcr_last; @@ -152,21 +151,12 @@ tsfile_input_thread ( void *aux ) delta = 90000; delta *= 11; -#if PLATFORM_LINUX - delta += pcr_last_realtime; - slp.tv_sec = (delta / 1000000); - slp.tv_nsec = (delta % 1000000) * 1000; - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &slp, NULL); -#else - slp.tv_sec = (delta / 1000000); - slp.tv_nsec = (delta % 1000000) * 1000; - nanosleep(&slp, NULL); -#endif + do { + r = tvh_usleep_abs(pcr_last_mono + delta); + } while (ERRNO_AGAIN(r) || r > 0); } - pcr_last = pcr.pcr_first; -#if PLATFORM_LINUX - pcr_last_realtime = getfastmonoclock(); -#endif + pcr_last = pcr.pcr_first; + pcr_last_mono = getfastmonoclock(); } } sched_yield(); diff --git a/src/notify.c b/src/notify.c index f039f1330..4c7dd8f18 100644 --- a/src/notify.c +++ b/src/notify.c @@ -110,7 +110,7 @@ notify_thread ( void *p ) htsmsg_destroy(q); /* Wait */ - usleep(500000); + tvh_safe_usleep(500000); pthread_mutex_lock(¬ify_mutex); } pthread_mutex_unlock(¬ify_mutex); diff --git a/src/satip/rtp.c b/src/satip/rtp.c index 8d6a0078d..34c6847f5 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -861,20 +861,21 @@ static void * satip_rtcp_thread(void *aux) { satip_rtp_session_t *rtp; - struct timespec ts; + int64_t us; uint8_t msg[RTCP_PAYLOAD+1]; char addrbuf[50]; int r, len, err; tvhtrace("satips", "starting rtcp thread"); while (satip_rtcp_run) { - ts.tv_sec = 0; - ts.tv_nsec = 150000000; + us = 150000; do { - r = nanosleep(&ts, &ts); + us = tvh_usleep(us); + if (us < 0) + goto end; if (!satip_rtcp_run) goto end; - } while (r && ts.tv_nsec); + } while (us > 0); pthread_mutex_lock(&satip_rtp_lock); TAILQ_FOREACH(rtp, &satip_rtp_sessions, link) { if (rtp->sq == NULL) continue; diff --git a/src/tcp.c b/src/tcp.c index bdb8e3808..a0eb97826 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -548,7 +548,7 @@ try_again: return NULL; } pthread_mutex_unlock(&global_lock); - usleep(250000); + tvh_safe_usleep(250000); pthread_mutex_lock(&global_lock); if (tvheadend_running) goto try_again; @@ -1116,7 +1116,7 @@ tcp_server_done(void) while (LIST_FIRST(&tcp_server_active) != NULL) { if (t + sec2mono(5) < getfastmonoclock()) tvhtrace("tcp", "tcp server %p active too long", LIST_FIRST(&tcp_server_active)); - usleep(20000); + tvh_safe_usleep(20000); } pthread_mutex_lock(&global_lock); diff --git a/src/udp.c b/src/udp.c index 3f33b3c4f..7f0a6e12f 100644 --- a/src/udp.c +++ b/src/udp.c @@ -472,7 +472,7 @@ udp_write( udp_connection_t *uc, const void *buf, size_t len, sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); if (r < 0) { if (ERRNO_AGAIN(errno)) { - usleep(100); + tvh_safe_usleep(100); continue; } break; diff --git a/src/upnp.c b/src/upnp.c index 7421e56c6..10927e149 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -216,7 +216,7 @@ upnp_thread( void *aux ) pthread_mutex_unlock(&upnp_lock); if (data == NULL) break; - usleep((long)data->delay_ms * 1000); + tvh_safe_usleep((long)data->delay_ms * 1000); upnp_dump_data(data); udp_write_queue(unicast, &data->queue, &data->storage); htsbuf_queue_flush(&data->queue); diff --git a/src/webui/comet.c b/src/webui/comet.c index 176754dc9..f0500e49e 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -243,7 +243,7 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) htsmsg_t *m; if(!im) - usleep(100000); /* Always sleep 0.1 sec to avoid comet storms */ + tvh_safe_usleep(100000); /* Always sleep 0.1 sec to avoid comet storms */ pthread_mutex_lock(&comet_mutex); if (!comet_running) { diff --git a/src/webui/webui.c b/src/webui/webui.c index 49b493865..e23430f28 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -400,7 +400,7 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, while (getfastmonoclock() < mono) { if (tcp_socket_dead(hc->hc_fd)) break; - usleep(50000); + tvh_safe_usleep(50000); } return; } diff --git a/src/wrappers.c b/src/wrappers.c index f08c28e13..5dfb8836c 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -87,7 +87,7 @@ tvh_write(int fd, const void *buf, size_t len) if (ERRNO_AGAIN(errno)) { if (mdispatch_clock > limit) break; - usleep(100); + tvh_safe_usleep(100); continue; } break; @@ -208,7 +208,7 @@ tvh_mutex_timedlock if (getfastmonoclock() >= finish) return ETIMEDOUT; - usleep(10000); + tvh_safe_usleep(10000); } return retcode; @@ -269,6 +269,61 @@ tvh_cond_timedwait return pthread_cond_timedwait(&cond->cond, mutex, &ts); } +/* + * clocks + */ + +void +tvh_safe_usleep(int64_t us) +{ + int64_t r; + if (us <= 0) + return; + do { + r = tvh_usleep(us); + if (r < 0) { + if (ERRNO_AGAIN(r)) + continue; + break; + } + us = r; + } while (r > 0); +} + +int64_t +tvh_usleep(int64_t us) +{ + struct timespec ts; + int64_t val; + int r; + if (us <= 0) + return 0; + ts.tv_sec = us / 1000000LL; + ts.tv_nsec = (us % 1000000LL) * 1000LL; + r = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + val = (ts.tv_sec * 1000000LL) + ((ts.tv_nsec + 500LL) / 1000LL); + if (ERRNO_AGAIN(r)) + return val; + return r ? -r : 0; +} + +int64_t +tvh_usleep_abs(int64_t us) +{ + struct timespec ts; + int64_t val; + int r; + if (us <= 0) + return 0; + ts.tv_sec = us / 1000000LL; + ts.tv_nsec = (us % 1000000LL) * 1000LL; + r = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, &ts); + val = (ts.tv_sec * 1000000LL) + ((ts.tv_nsec + 500LL) / 1000LL); + if (ERRNO_AGAIN(r)) + return val; + return r ? -r : 0; +} + /* * qsort */ -- 2.47.3