aboutsummaryrefslogtreecommitdiffstats
path: root/funcs
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-09-30 03:05:04 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-09-30 03:05:04 +0000
commit63c3a28cccdf66c30d4b3b9d733b822e80fa13ff (patch)
tree9e674ca8bb87b4bb3a8e6272af76778e960b056a /funcs
parenta183e3c1651415942cb7b04fa45c1e71d93549b4 (diff)
* The documentation for the LOCK() function says that it will block for up to
3 seconds while waiting on a lock when other locks are currently held to avoid deadlocks. Change the code to reflect this. * Since trying to grab a lock may block for some time, put the channel in autoservice so that audio is still read from the channel and that any active generators on the channel don't pause. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@84143 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'funcs')
-rw-r--r--funcs/func_lock.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/funcs/func_lock.c b/funcs/func_lock.c
index 8c08f85c6..b8c685340 100644
--- a/funcs/func_lock.c
+++ b/funcs/func_lock.c
@@ -187,11 +187,12 @@ static int get_lock(struct ast_channel *chan, char *lockname, int try)
/* Okay, we have both frames, so now we need to try to lock the mutex. */
if (count_channel_locks > 1) {
- /* If we fail after a certain number of attempts, assume a possible deadlock and bail. */
- int x;
- for (x = 0; x < 30; x++) {
+ struct timeval start = ast_tvnow();
+ for (;;) {
if ((res = ast_mutex_trylock(&current->mutex)) == 0)
break;
+ if (ast_tvdiff_ms(ast_tvnow(), start) > 3000)
+ break; /* bail after 3 seconds of waiting */
usleep(1);
}
} else {
@@ -256,13 +257,19 @@ static int unlock_read(struct ast_channel *chan, const char *cmd, char *data, ch
static int lock_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
+ ast_autoservice_start(chan);
ast_copy_string(buf, get_lock(chan, data, 0) ? "0" : "1", len);
+ ast_autoservice_stop(chan);
+
return 0;
}
static int trylock_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
+ ast_autoservice_start(chan);
ast_copy_string(buf, get_lock(chan, data, 1) ? "0" : "1", len);
+ ast_autoservice_stop(chan);
+
return 0;
}