/* PIDs list */
uint16_t ct_pids[MAX_PIDS];
+ uint8_t ct_multipid;
/* Elementary stream types */
uint8_t ct_types[MAX_PIDS];
mpegts_service_t *t;
capmt_service_t *ct;
uint16_t *pids;
- int i, j, pid, multipid;
+ int i, j, pid;
pthread_mutex_lock(&capmt->capmt_mutex);
LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
if (adapter != ct->ct_adapter)
continue;
- multipid = descrambler_multi_pid((th_descrambler_t *)ct);
-
pids = cai->pids;
for (i = 0; i < MAX_PIDS; i++) {
pid = ct->ct_pids[j];
if (pid == 0) break;
if (pid == pids[i]) {
- if (multipid) {
+ if (ct->ct_multipid) {
ct->ct_ok_flag = 1;
descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd);
continue;
ct = calloc(1, sizeof(capmt_service_t));
ct->ct_capmt = capmt;
ct->ct_adapter = tuner;
+ ct->ct_multipid = descrambler_multi_pid((th_descrambler_t *)ct);
i = 0;
TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
void dvr_inotify_done ( void )
{
int fd = atomic_exchange(&_inot_fd, -1);
- if (fd >= 0) close(fd);
+ if (fd >= 0) blacklisted_close(fd);
pthread_kill(dvr_inotify_tid, SIGTERM);
pthread_join(dvr_inotify_tid, NULL);
SKEL_FREE(dvr_inotify_entry_skel);
*/
static void *_epggrab_socket_thread ( void *p )
{
- int s;
+ int s, s1;
epggrab_module_ext_t *mod = (epggrab_module_ext_t*)p;
tvhinfo(mod->subsys, "%s: external socket enabled", mod->id);
- while ( mod->enabled && mod->sock ) {
+ while ( mod->enabled && (s1 = atomic_get(&mod->sock)) ) {
tvhdebug(mod->subsys, "%s: waiting for connection", mod->id);
- s = accept(mod->sock, NULL, NULL);
+ s = accept(s1, NULL, NULL);
if (s <= 0) continue;
tvhdebug(mod->subsys, "%s: got connection %d", mod->id, s);
_epggrab_socket_handler(mod, s);
assert(mod->type == EPGGRAB_EXT);
mod->active = 0;
- sock = mod->sock;
- mod->sock = 0;
+ sock = atomic_exchange(&mod->sock, 0);
shutdown(sock, SHUT_RDWR);
close(sock);
if (mod->tid) {
unlink(mod->path); // just in case!
hts_settings_makedirs(mod->path);
- mod->sock = socket(AF_UNIX, SOCK_STREAM, 0);
- assert(mod->sock);
+ atomic_set(&mod->sock, socket(AF_UNIX, SOCK_STREAM, 0));
+ assert(atomic_get(&mod->sock));
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
fsmonitor_done ( void )
{
int fd = atomic_exchange(&fsmonitor_fd, -1);
- if (fd >= 0) close(fd);
+ if (fd >= 0) blacklisted_close(fd);
pthread_kill(fsmonitor_tid, SIGTERM);
pthread_join(fsmonitor_tid, NULL);
}
th_pkt_t *n = malloc(sizeof(th_pkt_t));
if (n) {
- *n = *pkt;
+ blacklisted_memcpy(n, pkt, sizeof(*pkt));
n->pkt_refcount = 1;
streaming_queue_info(void *opaque, htsmsg_t *list)
{
streaming_queue_t *sq = opaque;
+ size_t size;
char buf[256];
- snprintf(buf, sizeof(buf), "streaming queue %p size %zd", sq, sq->sq_size);
+ pthread_mutex_lock(&sq->sq_mutex);
+ size = sq->sq_size;
+ pthread_mutex_unlock(&sq->sq_mutex);
+ snprintf(buf, sizeof(buf), "streaming queue %p size %zd", sq, size);
htsmsg_add_str(list, NULL, buf);
return list;
}
#define TVH_NAME_LEN 32
#define TVH_TITLE_LEN 256
+/* sanitizer helpers */
+#if __has_feature(thread_sanitizer)
+void *blacklisted_memcpy(void *dest, const void *src, size_t n);
+int blacklisted_close(int fildes);
+#else
+#define blacklisted_memcpy memcpy
+#define blacklisted_close close
+#endif
+
#endif /* TVHEADEND_H */
}
#endif
}
+
+/*
+ * Sanitizer helpers to avoid false positives
+ */
+#if __has_feature(thread_sanitizer)
+void *blacklisted_memcpy(void *dest, const void *src, size_t n)
+ __attribute__((no_sanitize("thread")))
+{
+ uint8_t *d = dest, *s = src;
+ while (n-- > 0) *d++ = *s++;
+ return dest;
+}
+
+void *dlsym(void *handle, const char *symbol);
+
+int blacklisted_close(int fd)
+ __attribute__((no_sanitize("thread")))
+{
+ // close(fd); // sanitizer reports errors in close()
+ return 0;
+}
+#endif