From: Jaroslav Kysela Date: Thu, 10 Mar 2016 10:03:26 +0000 (+0100) Subject: subscriptions: use ths_state atomically (clang sanitizer) X-Git-Tag: v4.2.1~902 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6b3a50608c44407d347c1faa78dec1cb8e65afa9;p=thirdparty%2Ftvheadend.git subscriptions: use ths_state atomically (clang sanitizer) --- diff --git a/src/subscriptions.c b/src/subscriptions.c index be5ca766b..c369ec51e 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -62,6 +62,18 @@ shortid(th_subscription_t *s) return s->ths_id & 0xffff; } +static inline void +subsetstate(th_subscription_t *s, ths_state_t state) +{ + atomic_set(&s->ths_state, state); +} + +static inline ths_state_t +subgetstate(th_subscription_t *s) +{ + return atomic_get(&s->ths_state); +} + /* ************************************************************************** * Subscription linking * *************************************************************************/ @@ -73,7 +85,7 @@ static void subscription_link_service(th_subscription_t *s, service_t *t) { streaming_message_t *sm; - s->ths_state = SUBSCRIPTION_TESTING_SERVICE; + subsetstate(s, SUBSCRIPTION_TESTING_SERVICE); s->ths_service = t; LIST_INSERT_HEAD(&t->s_subscriptions, s, ths_service_link); @@ -102,7 +114,7 @@ subscription_link_service(th_subscription_t *s, service_t *t) if(s->ths_start_message != NULL && t->s_streaming_status & TSS_PACKETS) { - s->ths_state = SUBSCRIPTION_GOT_SERVICE; + subsetstate(s, SUBSCRIPTION_GOT_SERVICE); // Send a START message to the subscription client streaming_target_deliver(s->ths_output, s->ths_start_message); @@ -326,7 +338,7 @@ subscription_reschedule(void) if(t != NULL && s->ths_current_instance != NULL) { /* Already got a service */ - if(s->ths_state != SUBSCRIPTION_BAD_SERVICE) + if(subgetstate(s) != SUBSCRIPTION_BAD_SERVICE) continue; /* And it not bad, so we're happy */ tvhwarn("subscription", "%04X: service instance is bad, reason: %s", @@ -451,7 +463,7 @@ static void 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) { + if (sm->sm_type == SMT_STOP && subgetstate(s) != SUBSCRIPTION_ZOMBIE) { LIST_INSERT_HEAD(&subscriptions_remove, s, ths_remove_link); mtimer_arm_rel(&subscription_reschedule_timer, subscription_reschedule_cb, NULL, 0); @@ -494,7 +506,7 @@ subscription_input(void *opauqe, streaming_message_t *sm) int error; th_subscription_t *s = opauqe; - if(s->ths_state == SUBSCRIPTION_TESTING_SERVICE) { + if(subgetstate(s) == SUBSCRIPTION_TESTING_SERVICE) { // We are just testing if this service is good if(sm->sm_type == SMT_GRACE) { @@ -517,7 +529,7 @@ subscription_input(void *opauqe, streaming_message_t *sm) (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) { if (error > s->ths_testing_error) s->ths_testing_error = error; - s->ths_state = SUBSCRIPTION_BAD_SERVICE; + subsetstate(s, SUBSCRIPTION_BAD_SERVICE); streaming_msg_free(sm); } return; @@ -531,11 +543,11 @@ subscription_input(void *opauqe, streaming_message_t *sm) if (s->ths_service) s->ths_service->s_running = 1; } - s->ths_state = SUBSCRIPTION_GOT_SERVICE; + subsetstate(s, SUBSCRIPTION_GOT_SERVICE); } } - if(s->ths_state != SUBSCRIPTION_GOT_SERVICE) { + if(subgetstate(s) != SUBSCRIPTION_GOT_SERVICE) { streaming_msg_free(sm); return; } @@ -601,14 +613,14 @@ subscription_unsubscribe(th_subscription_t *s, int flags) t = s->ths_service; raw = s->ths_raw_service; - if (s->ths_state == SUBSCRIPTION_ZOMBIE) { + if (subgetstate(s) == SUBSCRIPTION_ZOMBIE) { if ((flags & UNSUBSCRIBE_FINAL) != 0) { subscription_destroy(s); return; } abort(); } - s->ths_state = SUBSCRIPTION_ZOMBIE; + subsetstate(s, SUBSCRIPTION_ZOMBIE); LIST_REMOVE(s, ths_global_link); LIST_SAFE_REMOVE(s, ths_remove_link); @@ -889,7 +901,7 @@ subscription_create_msg(th_subscription_t *s, const char *lang) htsmsg_add_u32(m, "errors", atomic_get(&s->ths_total_err)); const char *state; - switch(s->ths_state) { + switch(subgetstate(s)) { default: state = N_("Idle"); break; diff --git a/src/subscriptions.h b/src/subscriptions.h index 510a1a0bf..e7e76ed1e 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -57,6 +57,15 @@ extern struct th_subscription_list subscriptions; #define UNSUBSCRIBE_QUIET 0x01 #define UNSUBSCRIBE_FINAL 0x02 +/* States */ +typedef enum { + SUBSCRIPTION_IDLE, + SUBSCRIPTION_TESTING_SERVICE, + SUBSCRIPTION_GOT_SERVICE, + SUBSCRIPTION_BAD_SERVICE, + SUBSCRIPTION_ZOMBIE +} ths_state_t; + typedef struct th_subscription { int ths_id; @@ -68,13 +77,7 @@ typedef struct th_subscription { int ths_weight; - enum { - SUBSCRIPTION_IDLE, - SUBSCRIPTION_TESTING_SERVICE, - SUBSCRIPTION_GOT_SERVICE, - SUBSCRIPTION_BAD_SERVICE, - SUBSCRIPTION_ZOMBIE - } ths_state; + int ths_state; int ths_testing_error;