diff --git a/src/atomic.h b/src/atomic.h index e9ef2648..1c3eb5ae 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -24,6 +24,12 @@ atomic_add(volatile int *ptr, int incr) return __sync_fetch_and_add(ptr, incr); } +static inline int +atomic_dec(volatile int *ptr, int decr) +{ + return __sync_fetch_and_sub(ptr, decr); +} + static inline int atomic_exchange(volatile int *ptr, int new) { diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 36c9e39f..b424b5e4 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -24,6 +24,7 @@ #error "Use header file input.h not input/mpegts.h" #endif +#include "atomic.h" #include "input.h" #include "service.h" #include "mpegts/dvb.h" @@ -198,7 +199,7 @@ struct mpegts_table int mt_mask; // mask int mt_destroyed; // Refcounting - int mt_refcount; + int mt_arefcount; int8_t mt_cc; @@ -794,14 +795,19 @@ void mpegts_input_close_pid void mpegts_table_dispatch (const uint8_t *sec, size_t r, void *mt); static inline void mpegts_table_grab - (mpegts_table_t *mt) { mt->mt_refcount++; } + (mpegts_table_t *mt) +{ + int v = atomic_add(&mt->mt_arefcount, 1); + assert(v > 0); +} void mpegts_table_release_ (mpegts_table_t *mt); static inline void mpegts_table_release (mpegts_table_t *mt) { - assert(mt->mt_refcount > 0); - if(--mt->mt_refcount == 0) { + int v = atomic_dec(&mt->mt_arefcount, 1); + assert(v > 0); + if (v == 1) { assert(mt->mt_destroyed == 1); mpegts_table_release_(mt); } diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 1e532467..2dfb8bb0 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -241,16 +241,16 @@ mpegts_table_add /* Create */ mt = calloc(1, sizeof(mpegts_table_t)); - mt->mt_refcount = 1; - mt->mt_name = strdup(name); - mt->mt_callback = callback; - mt->mt_opaque = opaque; - mt->mt_pid = pid; - mt->mt_flags = flags & ~(MT_SKIPSUBS|MT_SCANSUBS); - mt->mt_table = tableid; - mt->mt_mask = mask; - mt->mt_mux = mm; - mt->mt_cc = -1; + mt->mt_arefcount = 1; + mt->mt_name = strdup(name); + mt->mt_callback = callback; + mt->mt_opaque = opaque; + mt->mt_pid = pid; + mt->mt_flags = flags & ~(MT_SKIPSUBS|MT_SCANSUBS); + mt->mt_table = tableid; + mt->mt_mask = mask; + mt->mt_mux = mm; + mt->mt_cc = -1; /* Open table */ if (pid < 0) {