TT#91151 use auto cleanup for call unlock/unref

Change-Id: Ife9bac7b077fe5036147873992a044d663a83300
pull/1307/head
Richard Fuchs 5 years ago
parent 18601d708f
commit 432cf82f71

@ -301,6 +301,12 @@ static void streams_parse(const char *s, GQueue *q) {
i = 0;
pcre_multi_match(streams_re, streams_ree, s, 3, streams_parse_func, &i, q);
}
static void call_unlock_release(struct call **c) {
if (!*c)
return;
rwlock_unlock_w(&(*c)->master_lock);
obj_put(*c);
}
@ -381,7 +387,7 @@ str *call_delete_udp(char **out) {
return str_sprintf("%s 0\n", out[RE_UDP_COOKIE]);
}
str *call_query_udp(char **out) {
struct call *c;
AUTO_CLEANUP_NULL(struct call *c, call_unlock_release);
str *ret, callid, fromtag, totag;
struct call_stats stats;
@ -410,14 +416,8 @@ str *call_query_udp(char **out) {
goto out;
err:
if (c)
rwlock_unlock_w(&c->master_lock);
ret = str_sprintf("%s E8\n", out[RE_UDP_COOKIE]);
goto out;
out:
if (c)
obj_put(c);
return ret;
}
@ -2017,14 +2017,14 @@ found:
// XXX these are all identical - unify and use a flags int and/or callback
const char *call_start_forwarding_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Start forwarding for single party (tag '" STR_FORMAT_M "')",
@ -2037,25 +2037,18 @@ const char *call_start_forwarding_ng(bencode_item_t *input, bencode_item_t *outp
}
recording_start(call, NULL, &flags.metadata, NULL);
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return errstr;
return NULL;
}
const char *call_stop_forwarding_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Stop forwarding for single party (tag '" STR_FORMAT_M "')",
@ -2075,25 +2068,18 @@ const char *call_stop_forwarding_ng(bencode_item_t *input, bencode_item_t *outpu
recording_stop(call, NULL);
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return NULL;
}
const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Blocking directional DTMF (tag '" STR_FORMAT_M "')",
@ -2105,25 +2091,18 @@ const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
call->block_dtmf = 1;
}
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return errstr;
return NULL;
}
const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Unblocking directional DTMF (tag '" STR_FORMAT_M "')",
@ -2141,25 +2120,18 @@ const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output)
}
}
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return NULL;
}
const char *call_block_media_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Blocking directional media (tag '" STR_FORMAT_M "')",
@ -2173,25 +2145,18 @@ const char *call_block_media_ng(bencode_item_t *input, bencode_item_t *output) {
__call_unkernelize(call);
}
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return errstr;
return NULL;
}
const char *call_unblock_media_ng(bencode_item_t *input, bencode_item_t *output) {
struct call *call;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_OTHER);
if (errstr)
goto out;
return errstr;
if (monologue) {
ilog(LOG_INFO, "Unblocking directional media (tag '" STR_FORMAT_M "')",
@ -2211,13 +2176,6 @@ const char *call_unblock_media_ng(bencode_item_t *input, bencode_item_t *output)
__call_unkernelize(call);
}
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return NULL;
}
@ -2248,15 +2206,15 @@ static const char *play_media_select_party(struct call **call, GQueue *monologue
const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
#ifdef WITH_TRANSCODING
str str;
struct call *call;
GQueue monologues;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
AUTO_CLEANUP(GQueue monologues, g_queue_clear);
const char *err = NULL;
long long db_id;
long long repeat_times = 1;
err = play_media_select_party(&call, &monologues, input);
if (err)
goto out;
return err;
for (GList *l = monologues.head; l; l = l->next) {
struct call_monologue *monologue = l->data;
@ -2264,38 +2222,26 @@ const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
if (!monologue->player)
monologue->player = media_player_new(monologue);
repeat_times = bencode_dictionary_get_int_str(input, "repeat-times", 1);
err = "No media file specified";
if (bencode_dictionary_get_str(input, "file", &str)) {
err = "Failed to start media playback from file";
if (media_player_play_file(monologue->player, &str,repeat_times))
goto out;
return "Failed to start media playback from file";
}
else if (bencode_dictionary_get_str(input, "blob", &str)) {
err = "Failed to start media playback from blob";
if (media_player_play_blob(monologue->player, &str,repeat_times))
goto out;
return "Failed to start media playback from blob";
}
else if ((db_id = bencode_dictionary_get_int_str(input, "db-id", 0)) > 0) {
err = "Failed to start media playback from database";
if (media_player_play_db(monologue->player, db_id,repeat_times))
goto out;
return "Failed to start media playback from database";
}
else
goto out;
return "No media file specified";
if (l == monologues.head && monologue->player->duration)
bencode_dictionary_add_integer(output, "duration", monologue->player->duration);
}
err = NULL;
out:
g_queue_clear(&monologues);
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return err;
return NULL;
#else
return "unsupported";
#endif
@ -2304,33 +2250,24 @@ out:
const char *call_stop_media_ng(bencode_item_t *input, bencode_item_t *output) {
#ifdef WITH_TRANSCODING
struct call *call;
GQueue monologues;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
AUTO_CLEANUP(GQueue monologues, g_queue_clear);
const char *err = NULL;
err = play_media_select_party(&call, &monologues, input);
if (err)
goto out;
return err;
for (GList *l = monologues.head; l; l = l->next) {
struct call_monologue *monologue = l->data;
err = "Not currently playing media";
if (!monologue->player)
goto out;
return "Not currently playing media";
media_player_stop(monologue->player);
}
err = NULL;
out:
g_queue_clear(&monologues);
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return err;
return NULL;
#else
return "unsupported";
#endif
@ -2339,14 +2276,14 @@ out:
const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
#ifdef WITH_TRANSCODING
struct call *call;
GQueue monologues;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
AUTO_CLEANUP(GQueue monologues, g_queue_clear);
str str;
const char *err = NULL;
err = play_media_select_party(&call, &monologues, input);
if (err)
goto out;
return err;
// validate input parameters
@ -2371,24 +2308,20 @@ const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
}
long long code = bencode_dictionary_get_int_str(input, "code", -1);
err = "Out of range 'code' specified";
if (code == -1) {
// try a string code
err = "No valid 'code' specified";
if (!bencode_dictionary_get_str(input, "code", &str))
goto out;
err = "Given 'code' is not a single digit";
return "No valid 'code' specified";
if (str.len != 1)
goto out;
return "Given 'code' is not a single digit";
code = dtmf_code_from_char(str.s[0]);
err = "Invalid 'code' character";
if (code == -1)
goto out;
return "Invalid 'code' character";
}
else if (code < 0)
goto out;
return "Out of range 'code' specified";
else if (code > 15)
goto out;
return "Out of range 'code' specified";
long long volume = bencode_dictionary_get_int_str(input, "volume", 8);
if (volume > 0)
@ -2408,9 +2341,8 @@ const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
goto found;
}
err = "Monologue has no media capable of DTMF injection";
return "Monologue has no media capable of DTMF injection";
// XXX fall back to generating a secondary stream
goto out;
found:
for (GList *k = monologue->subscribers.head; k; k = k->next) {
@ -2424,23 +2356,16 @@ found:
goto found_sink;
}
err = "Sink monologue has no media capable of DTMF playback";
goto out;
return "Sink monologue has no media capable of DTMF playback";
found_sink:
err = dtmf_inject(media, code, volume, duration, pause, sink);
if (err)
break;
return err;
}
}
out:
g_queue_clear(&monologues);
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return err;
return NULL;
#else
return "unsupported";
#endif

Loading…
Cancel
Save