More expansion of the deadlock avoidance macro, including a macro to do locking

of the channel lock


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@125020 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Tilghman Lesher
2008-06-25 02:34:11 +00:00
parent 15093f2a63
commit 94c4089f4e
6 changed files with 33 additions and 31 deletions

View File

@@ -898,10 +898,7 @@ static inline int ss7_grab(struct dahdi_pvt *pvt, struct dahdi_ss7 *pri)
do { do {
res = ast_mutex_trylock(&pri->lock); res = ast_mutex_trylock(&pri->lock);
if (res) { if (res) {
ast_mutex_unlock(&pvt->lock); DEADLOCK_AVOIDANCE(&pvt->lock);
/* Release the lock and try again */
usleep(1);
ast_mutex_lock(&pvt->lock);
} }
} while (res); } while (res);
/* Then break the poll */ /* Then break the poll */
@@ -3755,9 +3752,7 @@ static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_ch
ast_channel_lock(c0); ast_channel_lock(c0);
while (ast_channel_trylock(c1)) { while (ast_channel_trylock(c1)) {
ast_channel_unlock(c0); CHANNEL_DEADLOCK_AVOIDANCE(c0);
usleep(1);
ast_channel_lock(c0);
} }
p0 = c0->tech_pvt; p0 = c0->tech_pvt;
@@ -3927,9 +3922,7 @@ static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_ch
ast_channel_lock(c0); ast_channel_lock(c0);
while (ast_channel_trylock(c1)) { while (ast_channel_trylock(c1)) {
ast_channel_unlock(c0); CHANNEL_DEADLOCK_AVOIDANCE(c0);
usleep(1);
ast_channel_lock(c0);
} }
p0 = c0->tech_pvt; p0 = c0->tech_pvt;
@@ -4469,14 +4462,12 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
the private structure -- not especially easy or clean */ the private structure -- not especially easy or clean */
while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) { while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
/* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
ast_mutex_unlock(&p->lock); DLA_UNLOCK(&p->lock);
ast_channel_unlock(ast); CHANNEL_DEADLOCK_AVOIDANCE(ast);
usleep(1);
/* We can grab ast and p in that order, without worry. We should make sure /* We can grab ast and p in that order, without worry. We should make sure
nothing seriously bad has happened though like some sort of bizarre double nothing seriously bad has happened though like some sort of bizarre double
masquerade! */ masquerade! */
ast_channel_lock(ast); DLA_LOCK(&p->lock);
ast_mutex_lock(&p->lock);
if (p->owner != ast) { if (p->owner != ast) {
ast_log(LOG_WARNING, "This isn't good...\n"); ast_log(LOG_WARNING, "This isn't good...\n");
return NULL; return NULL;

View File

@@ -139,9 +139,7 @@ static void wakeup_sub(struct feature_pvt *p, int a)
for (;;) { for (;;) {
if (p->subs[a].owner) { if (p->subs[a].owner) {
if (ast_mutex_trylock(&p->subs[a].owner->lock)) { if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
ast_mutex_unlock(&p->lock); DEADLOCK_AVOIDANCE(&p->lock);
usleep(1);
ast_mutex_lock(&p->lock);
} else { } else {
ast_queue_frame(p->subs[a].owner, &null); ast_queue_frame(p->subs[a].owner, &null);
ast_mutex_unlock(&p->subs[a].owner->lock); ast_mutex_unlock(&p->subs[a].owner->lock);

View File

@@ -304,9 +304,7 @@ static int oh323_simulate_dtmf_end(const void *data)
ast_mutex_lock(&pvt->lock); ast_mutex_lock(&pvt->lock);
/* Don't hold pvt lock while trying to lock the channel */ /* Don't hold pvt lock while trying to lock the channel */
while(pvt->owner && ast_channel_trylock(pvt->owner)) { while(pvt->owner && ast_channel_trylock(pvt->owner)) {
ast_mutex_unlock(&pvt->lock); DEADLOCK_AVOIDANCE(&pvt->lock);
usleep(1);
ast_mutex_lock(&pvt->lock);
} }
if (pvt->owner) { if (pvt->owner) {

View File

@@ -2248,9 +2248,7 @@ retry:
if (owner) { if (owner) {
if (ast_channel_trylock(owner)) { if (ast_channel_trylock(owner)) {
ast_debug(3, "Avoiding IAX destroy deadlock\n"); ast_debug(3, "Avoiding IAX destroy deadlock\n");
ast_mutex_unlock(&iaxsl[callno]); DEADLOCK_AVOIDANCE(&iaxsl[callno]);
usleep(1);
ast_mutex_lock(&iaxsl[callno]);
goto retry; goto retry;
} }
} }

View File

@@ -219,15 +219,13 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra
/* Ensure that we have both channels locked */ /* Ensure that we have both channels locked */
while (other && ast_channel_trylock(other)) { while (other && ast_channel_trylock(other)) {
ast_mutex_unlock(&p->lock); DLA_UNLOCK(&p->lock);
if (us && us_locked) { if (us && us_locked) {
ast_channel_unlock(us); CHANNEL_DEADLOCK_AVOIDANCE(us);
} else {
usleep(1);
} }
usleep(1); DLA_LOCK(&p->lock);
if (us && us_locked) {
ast_channel_lock(us);
}
ast_mutex_lock(&p->lock);
other = isoutbound ? p->owner : p->chan; other = isoutbound ? p->owner : p->chan;
} }

View File

@@ -289,6 +289,21 @@ int ast_find_lock_info(void *lock_addr, const char **filename, int *lineno, cons
} \ } \
} while (0) } while (0)
#define DLA_UNLOCK(lock) \
do { \
const char *__filename, *__func, *__mutex_name; \
int __lineno; \
int __res = ast_find_lock_info(lock, &__filename, &__lineno, &__func, &__mutex_name); \
ast_mutex_unlock(lock);
#define DLA_LOCK(lock) \
if (__res < 0) { /* Shouldn't ever happen, but just in case... */ \
ast_mutex_lock(lock); \
} else { \
__ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
} \
} while (0)
static inline void ast_reentrancy_lock(struct ast_lock_track *lt) static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
{ {
pthread_mutex_lock(&lt->reentr_mutex); pthread_mutex_lock(&lt->reentr_mutex);
@@ -1429,6 +1444,10 @@ static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
usleep(1); \ usleep(1); \
ast_mutex_unlock(lock); ast_mutex_unlock(lock);
#define DLA_UNLOCK(lock) ast_mutex_unlock(lock)
#define DLA_LOCK(lock) ast_mutex_lock(lock)
typedef pthread_mutex_t ast_mutex_t; typedef pthread_mutex_t ast_mutex_t;
#define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE) #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)