#! /bin/sh /usr/share/dpatch/dpatch-run ## ast_channel_trylock_safe.dpatch by Philipp Berndt ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Add thread safe alternative to ast_mutex_lock(&chan->lock) ## DP: in case that chan might have gone away. ## DP: ## DP: In some occasions ast_mutex_lock(&chan->lock) is used where chan could ## DP: already have been freed. This is of course not thread-safe. ## DP: ## DP: In this case the only thread-safe way to atomically check for and lock a ## DP: channel would be to use channel_find_locked(). However this method has three ## DP: disadvantages in the described context: ## DP: ## DP: - It is somewhat slow because it needs to do string comparison. ## DP: - You need some other information (besides the channel pointer) by which to ## DP: search. ## DP: - By trying to lock 10 times the semantics of channel_find_lock is something ## DP: like a compromise between lock and trylock. ## DP: (This is not what you want because if you can't lock chan->lock you ## DP: will probably want to release locks on mutexes outside of ## DP: channel_find_locked(), too before you try again.) @DPATCH@ diff -urNad asterisk-1.2.13~dfsg~/channel.c asterisk-1.2.13~dfsg/channel.c --- asterisk-1.2.13~dfsg~/channel.c 2006-09-27 18:54:30.000000000 +0200 +++ asterisk-1.2.13~dfsg/channel.c 2008-02-08 17:38:31.000000000 +0100 @@ -821,5 +821,22 @@ } +/*--- ast_channel_trylock_safe: Search for channel in list and try to lock it */ +int ast_channel_trylock_safe(struct ast_channel *ptr) +{ + int res = EINVAL; + struct ast_channel *c; + + ast_mutex_lock(&chlock); + for (c = channels; c; c = c->next) { + if (c == ptr) { + res = ast_mutex_trylock( &c->lock ); + break; + } + } + ast_mutex_unlock(&chlock); + return res; +} + /*--- ast_safe_sleep_conditional: Wait, look for hangups and condition arg */ int ast_safe_sleep_conditional( struct ast_channel *chan, int ms, int (*cond)(void*), void *data ) --- asterisk-1.2.13~dfsg~/include/asterisk/channel.h 2006-09-26 22:38:06.000000000 +0200 +++ asterisk-1.2.13~dfsg/include/asterisk/channel.h 2008-02-08 17:37:34.000000000 +0100 @@ -842,4 +842,7 @@ +/*! ast_channel_trylock_safe: Search for channel in list and try to lock it */ +int ast_channel_trylock_safe(struct ast_channel *ptr); + /*! Waits for a digit */ /*! * \param c channel to wait for a digit on