[asterisk-commits] bebuild: tag 10.3.0-rc3 r360467 - in /tags/10.3.0-rc3: ./ apps/ include/aster...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Mar 26 10:34:39 CDT 2012
Author: bebuild
Date: Mon Mar 26 10:34:35 2012
New Revision: 360467
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=360467
Log:
Merged 359980, 359694, 359707 for RC3
Removed:
tags/10.3.0-rc3/asterisk-10.3.0-rc2-summary.html
tags/10.3.0-rc3/asterisk-10.3.0-rc2-summary.txt
Modified:
tags/10.3.0-rc3/ (props changed)
tags/10.3.0-rc3/.version
tags/10.3.0-rc3/ChangeLog
tags/10.3.0-rc3/apps/app_milliwatt.c
tags/10.3.0-rc3/include/asterisk/manager.h
tags/10.3.0-rc3/main/manager.c
tags/10.3.0-rc3/main/utils.c
Propchange: tags/10.3.0-rc3/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.
Propchange: tags/10.3.0-rc3/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 26 10:34:35 2012
@@ -1,1 +1,1 @@
-/branches/10:357667
+/branches/10:357667,359694,359707,359980
Modified: tags/10.3.0-rc3/.version
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/.version?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/.version (original)
+++ tags/10.3.0-rc3/.version Mon Mar 26 10:34:35 2012
@@ -1,1 +1,1 @@
-10.3.0-rc2
+10.3.0-rc3
Modified: tags/10.3.0-rc3/ChangeLog
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/ChangeLog?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/ChangeLog (original)
+++ tags/10.3.0-rc3/ChangeLog Mon Mar 26 10:34:35 2012
@@ -1,3 +1,39 @@
+2012-03-26 Asterisk Development Team <asteriskteam at digium.com>
+
+ * Asterisk 10.3.0-rc3 Released.
+
+ * AST-2012-003
+
+ * AST-2012-002
+
+ * /main/manager.c, include/asterisk/manager.h: Fix AMI deadlock
+ regression by allowing AMI action callback to be reentrant
+
+ Fix AMI module reload deadlock from ASTERISK-18479 when it tired to
+ fix the race between calling an AMI action callback and
+ unregistering that action. Refixes ASTERISK-13874 broken by
+ ASTERISK-17785 change.
+
+ Locking the ao2 object guaranteed that there were no active
+ callbacks that mattered when ast_manager_unregister() was called.
+ Unfortunately, this causes the deadlock situation. The path stops
+ locking the ao2 object to allow multiple threads to invoke the
+ callback re-entrantly. There is no way to guarantee a module unload
+ will not crash because of an active callback. The code attempts to
+ minimize the chance with the registered flag and the maximum 5
+ second delay before ast_manager_unregister() returns.
+
+ The trunk version of the patch changes the API to fix the race
+ condition correctly to prevent the module code from unloading from
+ memory while an action callback is active.
+
+ * Don't hold the lock while calling the AMI action callback.
+
+ (closes issue ASTERISK-19487)
+ Reported by: Philippe Lindheimer
+
+ Review: https://reviewboard.asterisk.org/r/1818/
+
2012-03-06 Asterisk Development Team <asteriskteam at digium.com>
* Asterisk 10.3.0-rc2 Released.
Modified: tags/10.3.0-rc3/apps/app_milliwatt.c
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/apps/app_milliwatt.c?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/apps/app_milliwatt.c (original)
+++ tags/10.3.0-rc3/apps/app_milliwatt.c Mon Mar 26 10:34:35 2012
@@ -78,7 +78,7 @@
static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
{
unsigned char buf[AST_FRIENDLY_OFFSET + 640];
- const int maxsamples = ARRAY_LEN(buf);
+ const int maxsamples = ARRAY_LEN(buf) - (AST_FRIENDLY_OFFSET / sizeof(buf[0]));
int i, *indexp = (int *) data;
struct ast_frame wf = {
.frametype = AST_FRAME_VOICE,
Modified: tags/10.3.0-rc3/include/asterisk/manager.h
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/include/asterisk/manager.h?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/include/asterisk/manager.h (original)
+++ tags/10.3.0-rc3/include/asterisk/manager.h Mon Mar 26 10:34:35 2012
@@ -160,6 +160,8 @@
* function and unregestring the AMI action object.
*/
unsigned int registered:1;
+ /*! Number of active func() calls in progress. */
+ unsigned int active_count;
};
/*! \brief External routines may register/unregister manager callbacks this way
Modified: tags/10.3.0-rc3/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/main/manager.c?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/main/manager.c (original)
+++ tags/10.3.0-rc3/main/manager.c Mon Mar 26 10:34:35 2012
@@ -1975,7 +1975,11 @@
ao2_lock(act_found);
if (act_found->registered && act_found->func) {
+ ++act_found->active_count;
+ ao2_unlock(act_found);
ret = act_found->func(&s, &m);
+ ao2_lock(act_found);
+ --act_found->active_count;
} else {
ret = -1;
}
@@ -4779,8 +4783,12 @@
ao2_lock(act_found);
if (act_found->registered && act_found->func) {
ast_debug(1, "Running action '%s'\n", act_found->action);
+ ++act_found->active_count;
+ ao2_unlock(act_found);
ret = act_found->func(s, m);
acted = 1;
+ ao2_lock(act_found);
+ --act_found->active_count;
}
ao2_unlock(act_found);
}
@@ -5288,6 +5296,8 @@
AST_RWLIST_UNLOCK(&actions);
if (cur) {
+ time_t now;
+
/*
* We have removed the action object from the container so we
* are no longer in a hurry.
@@ -5295,6 +5305,23 @@
ao2_lock(cur);
cur->registered = 0;
ao2_unlock(cur);
+
+ /*
+ * Wait up to 5 seconds for any active invocations to complete
+ * before returning. We have to wait instead of blocking
+ * because we may be waiting for ourself to complete.
+ */
+ now = time(NULL);
+ while (cur->active_count) {
+ if (5 <= time(NULL) - now) {
+ ast_debug(1,
+ "Unregister manager action %s timed out waiting for %d active instances to complete\n",
+ action, cur->active_count);
+ break;
+ }
+
+ sched_yield();
+ }
ao2_t_ref(cur, -1, "action object removed from list");
ast_verb(2, "Manager unregistered action %s\n", action);
Modified: tags/10.3.0-rc3/main/utils.c
URL: http://svnview.digium.com/svn/asterisk/tags/10.3.0-rc3/main/utils.c?view=diff&rev=360467&r1=360466&r2=360467
==============================================================================
--- tags/10.3.0-rc3/main/utils.c (original)
+++ tags/10.3.0-rc3/main/utils.c Mon Mar 26 10:34:35 2012
@@ -1989,9 +1989,28 @@
* pedantic arg can be set to nonzero if we need to do addition Digest check.
*/
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
- int i;
- char *c, key[512], val[512];
+ char *c;
struct ast_str *str = ast_str_create(16);
+
+ /* table of recognised keywords, and places where they should be copied */
+ const struct x {
+ const char *key;
+ const ast_string_field *field;
+ } *i, keys[] = {
+ { "username=", &d->username },
+ { "realm=", &d->realm },
+ { "nonce=", &d->nonce },
+ { "uri=", &d->uri },
+ { "domain=", &d->domain },
+ { "response=", &d->response },
+ { "cnonce=", &d->cnonce },
+ { "opaque=", &d->opaque },
+ /* Special cases that cannot be directly copied */
+ { "algorithm=", NULL },
+ { "qop=", NULL },
+ { "nc=", NULL },
+ { NULL, 0 },
+ };
if (ast_strlen_zero(digest) || !d || !str) {
ast_free(str);
@@ -2010,72 +2029,55 @@
c += strlen("Digest ");
/* lookup for keys/value pair */
- while (*c && *(c = ast_skip_blanks(c))) {
+ while (c && *c && *(c = ast_skip_blanks(c))) {
/* find key */
- i = 0;
- while (*c && *c != '=' && *c != ',' && !isspace(*c)) {
- key[i++] = *c++;
- }
- key[i] = '\0';
- c = ast_skip_blanks(c);
- if (*c == '=') {
- c = ast_skip_blanks(++c);
- i = 0;
- if (*c == '\"') {
- /* in quotes. Skip first and look for last */
- c++;
- while (*c && *c != '\"') {
- if (*c == '\\' && c[1] != '\0') { /* unescape chars */
- c++;
+ for (i = keys; i->key != NULL; i++) {
+ char *src, *separator;
+ int unescape = 0;
+ if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
+ continue;
+ }
+
+ /* Found. Skip keyword, take text in quotes or up to the separator. */
+ c += strlen(i->key);
+ if (*c == '"') {
+ src = ++c;
+ separator = "\"";
+ unescape = 1;
+ } else {
+ src = c;
+ separator = ",";
+ }
+ strsep(&c, separator); /* clear separator and move ptr */
+ if (unescape) {
+ ast_unescape_c(src);
+ }
+ if (i->field) {
+ ast_string_field_ptr_set(d, i->field, src);
+ } else {
+ /* Special cases that require additional procesing */
+ if (!strcasecmp(i->key, "algorithm=")) {
+ if (strcasecmp(src, "MD5")) {
+ ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
+ ast_free(str);
+ return -1;
}
- val[i++] = *c++;
- }
- } else {
- /* token */
- while (*c && *c != ',' && !isspace(*c)) {
- val[i++] = *c++;
+ } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
+ d->qop = 1;
+ } else if (!strcasecmp(i->key, "nc=")) {
+ unsigned long u;
+ if (sscanf(src, "%30lx", &u) != 1) {
+ ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
+ ast_free(str);
+ return -1;
+ }
+ ast_string_field_set(d, nc, src);
}
}
- val[i] = '\0';
- }
-
- while (*c && *c != ',') {
- c++;
- }
- if (*c) {
- c++;
- }
-
- if (!strcasecmp(key, "username")) {
- ast_string_field_set(d, username, val);
- } else if (!strcasecmp(key, "realm")) {
- ast_string_field_set(d, realm, val);
- } else if (!strcasecmp(key, "nonce")) {
- ast_string_field_set(d, nonce, val);
- } else if (!strcasecmp(key, "uri")) {
- ast_string_field_set(d, uri, val);
- } else if (!strcasecmp(key, "domain")) {
- ast_string_field_set(d, domain, val);
- } else if (!strcasecmp(key, "response")) {
- ast_string_field_set(d, response, val);
- } else if (!strcasecmp(key, "algorithm")) {
- if (strcasecmp(val, "MD5")) {
- ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", val);
- return -1;
- }
- } else if (!strcasecmp(key, "cnonce")) {
- ast_string_field_set(d, cnonce, val);
- } else if (!strcasecmp(key, "opaque")) {
- ast_string_field_set(d, opaque, val);
- } else if (!strcasecmp(key, "qop") && !strcasecmp(val, "auth")) {
- d->qop = 1;
- } else if (!strcasecmp(key, "nc")) {
- unsigned long u;
- if (sscanf(val, "%30lx", &u) != 1) {
- ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", val);
- return -1;
- }
- ast_string_field_set(d, nc, val);
+ break;
+ }
+ if (i->key == NULL) { /* not found, try ',' */
+ strsep(&c, ",");
}
}
ast_free(str);
More information about the asterisk-commits
mailing list