diff options
author | oej <oej@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-15 08:07:50 +0000 |
---|---|---|
committer | oej <oej@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-15 08:07:50 +0000 |
commit | f33b337077b11c3d312e9e0e87a1f675c8dd235b (patch) | |
tree | 8e37585dc242426cd3070d0e6771d0af748f60ca /channel.c | |
parent | 91102c5a2cae50a81cc3e135cad4d297aa5d71d6 (diff) |
New functions for locking a channel - these simplify debugging
when you have channel locking issues.
(Part of the SIP transfer patch, where I had a *lot* of
channel locking problems)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@20264 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rw-r--r-- | channel.c | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -4187,3 +4187,127 @@ const char *channelreloadreason2txt(enum channelreloadreason reason) return "MANAGERRELOAD (Channel module reload by manager)"; } }; + +#ifdef DEBUG_CHANNEL_LOCKS + +/*! \brief Unlock AST channel (and print debugging output) +\note You need to enable DEBUG_CHANNEL_LOCKS for this function +*/ +int ast_channel_unlock(struct ast_channel *chan) +{ + int res = 0; + if (option_debug > 2) + ast_log(LOG_DEBUG, "::::==== Unlocking AST channel %s\n", chan->name); + + if (!chan) { + ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n"); + return 0; + } + + res = ast_mutex_unlock(&chan->lock); + + if (option_debug > 2) { + /* Try to find counter if possible on your platform + I've only found out how to do this on Linux + DEBUG_THREADS changes the lock structure + */ +#ifdef __linux__ + int count = 0; +#ifdef DEBUG_THREADS + if ((count = chan->lock.mutex.__m_count)) +#else + if ((count = chan->lock.__m_count)) +#endif + ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count); +#endif + if (!res) + ast_log(LOG_DEBUG, "::::==== Channel %s was unlocked\n", chan->name); + if (res == EINVAL) { + ast_log(LOG_DEBUG, "::::==== Channel %s had no lock by this thread. Failed unlocking\n", chan->name); + } + } + if (res == EPERM) { + /* We had no lock, so okay any way*/ + if (option_debug > 3) + ast_log(LOG_DEBUG, "::::==== Channel %s was not locked at all \n", chan->name); + res = 0; + } + return res; +} + +/*! \brief Lock AST channel (and print debugging output) +\note You need to enable DEBUG_CHANNEL_LOCKS for this function */ +int ast_channel_lock(struct ast_channel *chan) +{ + int res; + + if (option_debug > 3) + ast_log(LOG_DEBUG, "====:::: Locking AST channel %s\n", chan->name); + + res = ast_mutex_lock(&chan->lock); + + if (option_debug > 3) { +#ifdef __linux__ + int count = 0; +#ifdef DEBUG_THREADS + if ((count = chan->lock.mutex.__m_count)) +#else + if ((count = chan->lock.__m_count)) +#endif + ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count); +#endif + if (!res) + ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name); + if (res == EDEADLK) { + /* We had no lock, so okey any way */ + if (option_debug > 3) + ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name); + } + if (res == EINVAL) { + if (option_debug > 3) + ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name); + } + } + return res; +} + +/*! \brief Lock AST channel (and print debugging output) +\note You need to enable DEBUG_CHANNEL_LOCKS for this function */ +int __ast_channel_trylock(struct ast_channel *chan) +{ + int res; + + if (option_debug > 2) + ast_log(LOG_DEBUG, "====:::: Trying to lock AST channel %s\n", chan->name); + + res = ast_mutex_trylock(&chan->lock); + + if (option_debug > 2) { +#ifdef __linux__ + int count = 0; +#ifdef DEBUG_THREADS + if ((count = chan->lock.mutex.__m_count)) +#else + if ((count = chan->lock.__m_count)) +#endif + ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count); +#endif + if (!res) + ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name); + if (res == EBUSY) { + /* We failed to lock */ + if (option_debug > 2) + ast_log(LOG_DEBUG, "::::==== Channel %s failed to lock. Not waiting around...\n", chan->name); + } + if (res == EDEADLK) { + /* We had no lock, so okey any way*/ + if (option_debug > 2) + ast_log(LOG_DEBUG, "::::==== Channel %s was not locked. Lock would cause deadlock.\n", chan->name); + } + if (res == EINVAL && option_debug > 2) + ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name); + } + return res; +} + +#endif |