From: Richard Mudgett Date: Tue, 26 Apr 2016 20:58:06 +0000 (-0500) Subject: res_pjsip_pubsub.c: Fix body generator registration race. X-Git-Tag: 13.10.0-rc1~111^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9e416f0538ee404906390e4b1c1a97cedf23075;p=thirdparty%2Fasterisk.git res_pjsip_pubsub.c: Fix body generator registration race. Change-Id: Id8752073ef06472a2fd96080f4009fac42843e67 --- diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index 6700475672..e744bad4fb 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -2541,20 +2541,28 @@ void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler AST_RWLIST_TRAVERSE_SAFE_END; } -static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype(const char *content_type, - const char *content_subtype) +static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype_nolock(const char *type, const char *subtype) { - struct ast_sip_pubsub_body_generator *iter; - SCOPED_LOCK(lock, &body_generators, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); + struct ast_sip_pubsub_body_generator *gen; - AST_LIST_TRAVERSE(&body_generators, iter, list) { - if (!strcmp(iter->type, content_type) && - !strcmp(iter->subtype, content_subtype)) { + AST_LIST_TRAVERSE(&body_generators, gen, list) { + if (!strcmp(gen->type, type) + && !strcmp(gen->subtype, subtype)) { break; } - }; + } - return iter; + return gen; +} + +static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype(const char *type, const char *subtype) +{ + struct ast_sip_pubsub_body_generator *gen; + + AST_RWLIST_RDLOCK(&body_generators); + gen = find_body_generator_type_subtype_nolock(type, subtype); + AST_RWLIST_UNLOCK(&body_generators); + return gen; } static struct ast_sip_pubsub_body_generator *find_body_generator_accept(const char *accept) @@ -3092,14 +3100,14 @@ int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator pj_str_t accept; pj_size_t accept_len; - existing = find_body_generator_type_subtype(generator->type, generator->subtype); + AST_RWLIST_WRLOCK(&body_generators); + existing = find_body_generator_type_subtype_nolock(generator->type, generator->subtype); if (existing) { - ast_log(LOG_WARNING, "Cannot register body generator of %s/%s." - "One is already registered.\n", generator->type, generator->subtype); + AST_RWLIST_UNLOCK(&body_generators); + ast_log(LOG_WARNING, "A body generator for %s/%s is already registered.\n", + generator->type, generator->subtype); return -1; } - - AST_RWLIST_WRLOCK(&body_generators); AST_LIST_INSERT_HEAD(&body_generators, generator, list); AST_RWLIST_UNLOCK(&body_generators);