aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 18:08:20 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 18:08:20 +0000
commit5767f353c49c6995efe206378c0f5532209f9f48 (patch)
tree3b5ef6bff93ccde619c1efe0652a0c16a0fa8480 /main
parent07d8da88112b3b31ee52b6a1b383435c577227f9 (diff)
Race condition between ast_cli_command() and 'module unload' could cause a deadlock.
Add lock timeouts to avoid this potential deadlock. (closes issue #14705) Reported by: jamessan Patches: 20090320__bug14705.diff.txt uploaded by tilghman (license 14) Tested by: jamessan git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@187428 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/manager.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/main/manager.c b/main/manager.c
index 54fe20805..65b6d8817 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -2608,8 +2608,12 @@ int manager_event(int category, const char *event, const char *fmt, ...)
int ast_manager_unregister(char *action)
{
struct manager_action *cur, *prev;
+ struct timespec tv = { 5, };
- ast_rwlock_wrlock(&actionlock);
+ if (ast_rwlock_timedwrlock(&actionlock, &tv)) {
+ ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
+ return -1;
+ }
cur = prev = first_action;
while (cur) {
if (!strcasecmp(action, cur->action)) {
@@ -2638,8 +2642,12 @@ static int ast_manager_register_struct(struct manager_action *act)
{
struct manager_action *cur, *prev = NULL;
int ret;
+ struct timespec tv = { 5, };
- ast_rwlock_wrlock(&actionlock);
+ if (ast_rwlock_timedwrlock(&actionlock, &tv)) {
+ ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
+ return -1;
+ }
cur = first_action;
while (cur) { /* Walk the list of actions */
ret = strcasecmp(cur->action, act->action);
@@ -2693,7 +2701,10 @@ int ast_manager_register2(const char *action, int auth, int (*func)(struct manse
cur->description = description;
cur->next = NULL;
- ast_manager_register_struct(cur);
+ if (ast_manager_register_struct(cur)) {
+ ast_free(cur);
+ return -1;
+ }
return 0;
}