[asterisk-commits] russell: branch russell/ast_channel_refcount r80537 - in /team/russell/ast_ch...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Aug 23 13:32:03 CDT 2007
Author: russell
Date: Thu Aug 23 13:32:02 2007
New Revision: 80537
URL: http://svn.digium.com/view/asterisk?view=rev&rev=80537
Log:
commit progress. I got most of the changes needed in channel.c except the
very hardest part - the channel_walk functions. That is going to take some
serious thought and planning and I don't feel like doing it right now. :)
Modified:
team/russell/ast_channel_refcount/build_tools/cflags.xml
team/russell/ast_channel_refcount/include/asterisk/astobj2.h
team/russell/ast_channel_refcount/include/asterisk/channel.h
team/russell/ast_channel_refcount/include/asterisk/lock.h
team/russell/ast_channel_refcount/main/astobj2.c
team/russell/ast_channel_refcount/main/channel.c
Modified: team/russell/ast_channel_refcount/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/build_tools/cflags.xml?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/build_tools/cflags.xml (original)
+++ team/russell/ast_channel_refcount/build_tools/cflags.xml Thu Aug 23 13:32:02 2007
@@ -1,6 +1,4 @@
<category name="MENUSELECT_CFLAGS" displayname="Compiler Flags" positive_output="yes" remove_on_change=".lastclean">
- <member name="DEBUG_CHANNEL_LOCKS" displayname="Debug Channel Locking">
- </member>
<member name="DEBUG_SCHEDULER" displayname="Enable Scheduler Debugging Output">
</member>
<member name="DEBUG_THREADS" displayname="Enable Thread Debugging">
Modified: team/russell/ast_channel_refcount/include/asterisk/astobj2.h
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/include/asterisk/astobj2.h?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/include/asterisk/astobj2.h (original)
+++ team/russell/ast_channel_refcount/include/asterisk/astobj2.h Thu Aug 23 13:32:02 2007
@@ -191,6 +191,15 @@
* \return 0 on success, other values on error.
*/
int ao2_lock(void *a);
+
+/*!
+ * \brief Try to lock an object.
+ *
+ * \param a A pointer to the object we want lock.
+ *
+ * \return 0 on success, other values on error.
+ */
+int ao2_trylock(void *a);
/*!
* Unlock an object.
Modified: team/russell/ast_channel_refcount/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/include/asterisk/channel.h?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/include/asterisk/channel.h (original)
+++ team/russell/ast_channel_refcount/include/asterisk/channel.h Thu Aug 23 13:32:02 2007
@@ -422,7 +422,6 @@
struct ast_channel_spy_list *spies; /*!< Chan Spy stuff */
struct ast_channel_whisper_buffer *whisper; /*!< Whisper Paging buffer */
- AST_LIST_ENTRY(ast_channel) chan_list; /*!< For easy linking */
struct ast_jb jb; /*!< The jitterbuffer state */
@@ -1374,6 +1373,9 @@
*/
char *ast_channel_reason2str(int reason);
+#define ast_channel_lock(c) ao2_lock(c)
+#define ast_channel_unlock(c) ao2_unlock(c)
+#define ast_channel_trylock(c) ao2_trylock(c)
#if defined(__cplusplus) || defined(c_plusplus)
}
Modified: team/russell/ast_channel_refcount/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/include/asterisk/lock.h?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/include/asterisk/lock.h (original)
+++ team/russell/ast_channel_refcount/include/asterisk/lock.h Thu Aug 23 13:32:02 2007
@@ -827,32 +827,4 @@
})
#endif
-#ifndef DEBUG_CHANNEL_LOCKS
-/*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_lock(x) ast_mutex_lock(&x->lock)
-/*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
-/*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
-#else
-
-struct ast_channel;
-
-/*! \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);
-
-/*! \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);
-
-/*! \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);
-#endif
-
#endif /* _ASTERISK_LOCK_H */
Modified: team/russell/ast_channel_refcount/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/main/astobj2.c?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/main/astobj2.c (original)
+++ team/russell/ast_channel_refcount/main/astobj2.c Thu Aug 23 13:32:02 2007
@@ -129,6 +129,22 @@
ast_atomic_fetchadd_int(&ao2.total_locked, 1);
return ast_mutex_lock(&p->priv_data.lock);
+}
+
+int ao2_trylock(void *user_data)
+{
+ struct astobj2 *p = INTERNAL_OBJ(user_data);
+ int res;
+
+ if (!p)
+ return -1;
+
+ res = ast_mutex_trylock(&p->priv_data.lock);
+
+ if (!res)
+ ast_atomic_fetchadd_int(&ao2.total_locked, 1);
+
+ return res;
}
int ao2_unlock(void *user_data)
Modified: team/russell/ast_channel_refcount/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/ast_channel_refcount/main/channel.c?view=diff&rev=80537&r1=80536&r2=80537
==============================================================================
--- team/russell/ast_channel_refcount/main/channel.c (original)
+++ team/russell/ast_channel_refcount/main/channel.c Thu Aug 23 13:32:02 2007
@@ -121,11 +121,14 @@
};
/*! the list of registered channel types */
-static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
-
-/*! the list of channels we have. Note that the lock for this list is used for
- both the channels list and the backends list. */
-static AST_LIST_HEAD_STATIC(channels, ast_channel);
+static AST_LIST_HEAD_STATIC(backends, chanlist);
+
+#ifdef LOW_MEMORY
+#define MAX_CHANNEL_BUCKETS 61
+#else
+#define MAX_CHANNEL_BUCKETS 1567
+#endif
+static ao2_container *channels;
/*! map AST_CAUSE's to readable string representations */
const struct ast_cause {
@@ -203,10 +206,7 @@
ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return -1;
- }
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, cl, list) {
ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
(cl->tech->devicestate) ? "yes" : "no",
@@ -214,7 +214,7 @@
(cl->tech->transfer) ? "yes" : "no");
count_chan++;
}
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
return RESULT_SUCCESS;
@@ -229,10 +229,7 @@
if (argc != 3)
return RESULT_SHOWUSAGE;
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return RESULT_FAILURE;
- }
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, cl, list) {
if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
@@ -243,7 +240,7 @@
if (!cl) {
ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return RESULT_FAILURE;
}
@@ -271,7 +268,8 @@
);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
+
return RESULT_SUCCESS;
}
@@ -282,10 +280,7 @@
if (argc != 4)
return RESULT_SHOWUSAGE;
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return RESULT_FAILURE;
- }
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, cl, list) {
if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
@@ -296,7 +291,7 @@
if (!cl) {
ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return RESULT_FAILURE;
}
@@ -324,7 +319,8 @@
);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
+
return RESULT_SUCCESS;
}
@@ -445,29 +441,28 @@
return b2;
}
+static ast_channel_softhangup_cb(void *obj, void *arg, int flags)
+{
+ struct ast_channel *chan = obj;
+
+ ast_softhangup(chan);
+
+ return 0;
+}
+
/*! \brief Initiate system shutdown */
void ast_begin_shutdown(int hangup)
{
struct ast_channel *c;
shutting_down = 1;
- if (hangup) {
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
- ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
- AST_LIST_UNLOCK(&channels);
- }
+ if (hangup)
+ ao2_callback(channels, OBJ_NODATA, ast_channel_softhangup_cb, NULL);
}
/*! \brief returns number of active/allocated channels */
int ast_active_channels(void)
{
- struct ast_channel *c;
- int cnt = 0;
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
- cnt++;
- AST_LIST_UNLOCK(&channels);
- return cnt;
+ return ao2_container_count(channels);
}
/*! \brief Cancel a shutdown in progress */
@@ -517,18 +512,18 @@
{
struct chanlist *chan;
- AST_LIST_LOCK(&channels);
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, chan, list) {
if (!strcasecmp(tech->type, chan->tech->type)) {
ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return -1;
}
}
if (!(chan = ast_calloc(1, sizeof(*chan)))) {
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return -1;
}
chan->tech = tech;
@@ -541,7 +536,7 @@
ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
chan->tech->description);
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return 0;
}
@@ -552,7 +547,7 @@
if (option_debug)
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
- AST_LIST_LOCK(&channels);
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
if (chan->tech == tech) {
@@ -565,7 +560,7 @@
}
AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
}
const struct ast_channel_tech *ast_get_channel_tech(const char *name)
@@ -573,19 +568,14 @@
struct chanlist *chanls;
const struct ast_channel_tech *ret = NULL;
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
- return NULL;
- }
-
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, chanls, list) {
if (!strcasecmp(name, chanls->tech->type)) {
ret = chanls->tech;
break;
}
}
-
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return ret;
}
@@ -724,6 +714,18 @@
.description = "Null channel (should not see this)",
};
+static inline struct ast_channel *ast_channel_ref(struct ast_channel *chan)
+{
+ ao2_ref(chan, +1);
+ return chan;
+}
+
+static inline struct ast_channel *ast_channel_unref(struct ast_channel *chan)
+{
+ ao2_ref(chan, -1);
+ return NULL;
+}
+
/*! \brief Create a new channel structure */
struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...)
{
@@ -739,18 +741,17 @@
return NULL;
}
- if (!(tmp = ast_calloc(1, sizeof(*tmp))))
+ if (!(tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor)))
return NULL;
if (!(tmp->sched = sched_context_create())) {
ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
- free(tmp);
+ ast_channel_unref(tmp);
return NULL;
}
if ((ast_string_field_init(tmp, 128))) {
- sched_context_destroy(tmp->sched);
- free(tmp);
+ ast_channel_unref(tmp);
return NULL;
}
@@ -776,8 +777,7 @@
if (needqueue) {
if (pipe(tmp->alertpipe)) {
ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
- ast_string_field_free_pools(tmp);
- free(tmp);
+ ast_channel_unref(tmp);
return NULL;
} else {
flags = fcntl(tmp->alertpipe[0], F_GETFL);
@@ -884,9 +884,7 @@
tmp->tech = &null_tech;
- AST_LIST_LOCK(&channels);
- AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
- AST_LIST_UNLOCK(&channels);
+ ao2_link(channels, ast_channel_ref(tmp));
return tmp;
}
@@ -1186,8 +1184,21 @@
free(cid->cid_rdnis);
}
-/*! \brief Free a channel structure */
-void ast_channel_free(struct ast_channel *chan)
+/*!
+ * \brief Unlink a channel from the channels container and also release
+ * this reference
+ *
+ * If this was the last reference to the channel, it will immediately
+ * go away. If not, it will go away when the last reference is released.
+ */
+struct ast_channel *ast_channel_free(struct ast_channel *chan)
+{
+ /* This is safe, even if it the object has already been unlinked */
+ ao2_unlink(channels, chan);
+ return ast_channel_unref(chan);
+}
+
+void ast_channel_destructor(struct ast_channel *chan)
{
int fd;
struct ast_var_t *vardata;
@@ -1196,19 +1207,10 @@
struct ast_datastore *datastore = NULL;
char name[AST_CHANNEL_NAME];
- headp=&chan->varshead;
-
- AST_LIST_LOCK(&channels);
- if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
- AST_LIST_UNLOCK(&channels);
- ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
- }
- /* Lock and unlock the channel just to be sure nobody
- has it locked still */
- ast_channel_lock(chan);
- ast_channel_unlock(chan);
+ headp = &chan->varshead;
+
if (chan->tech_pvt) {
- ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
+ ast_log(LOG_ERROR, "Channel '%s' may not have been hung up properly\n", chan->name);
free(chan->tech_pvt);
}
@@ -1262,12 +1264,9 @@
ast_app_group_discard(chan);
- /* Destroy the jitterbuffer */
ast_jb_destroy(chan);
ast_string_field_free_pools(chan);
- free(chan);
- AST_LIST_UNLOCK(&channels);
ast_device_state_changed_literal(name);
}
@@ -1780,7 +1779,7 @@
chan->hangupcause,
ast_cause2str(chan->hangupcause)
);
- ast_channel_free(chan);
+ chan = ast_channel_free(chan);
if (cdr)
ast_cdr_detach(cdr);
@@ -3200,11 +3199,7 @@
cause = &foo;
*cause = AST_CAUSE_NOTDEFINED;
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return NULL;
- }
-
+ AST_LIST_LOCK(&backends);
AST_LIST_TRAVERSE(&backends, chan, list) {
if (strcasecmp(type, chan->tech->type))
continue;
@@ -3215,10 +3210,10 @@
if (res < 0) {
ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
return NULL;
}
- AST_LIST_UNLOCK(&channels);
+ AST_LIST_UNLOCK(&backends);
if (!chan->tech->requester)
return NULL;
@@ -3228,10 +3223,10 @@
/* no need to generate a Newchannel event here; it is done in the channel_alloc call */
return c;
}
+ AST_LIST_UNLOCK(&backends);
ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
*cause = AST_CAUSE_NOSUCHDRIVER;
- AST_LIST_UNLOCK(&channels);
return NULL;
}
@@ -3816,7 +3811,7 @@
clone->hangupcause,
ast_cause2str(clone->hangupcause)
);
- ast_channel_free(clone);
+ clone = ast_channel_free(clone);
} else {
if (option_debug)
ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
@@ -4590,8 +4585,30 @@
ast_moh_cleanup_ptr(chan);
}
+/*!
+ * \note The only member of the channel passed here guaranteed to be set is the name field
+ */
+static int ast_channel_hash_cb(const void *obj, const int flags)
+{
+ const struct ast_channel *chan = obj;
+
+ return ast_str_hash(chan->name);
+}
+
+/*!
+ * \note The only member of the channel passed here guaranteed to be set is the name field
+ */
+static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct ast_channel *chan = obj, *chan2 = arg;
+
+ return !strcasecmp(chan->name, chan2->name) ? CMP_MATCH : 0;
+}
+
void ast_channels_init(void)
{
+ channels = ao2_container_alloc(MAX_CHANNEL_BUCKETS, ast_channel_hash, ast_channel_cmp);
+
ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
}
@@ -4848,117 +4865,6 @@
}
};
-#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) {
- if (option_debug)
- ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n");
- return 0;
- }
-
- res = ast_mutex_unlock(&chan->lock);
-
- if (option_debug > 2) {
-#ifdef DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count);
-#endif
- if (!res)
- if (option_debug)
- ast_log(LOG_DEBUG, "::::==== Channel %s was unlocked\n", chan->name);
- if (res == EINVAL) {
- if (option_debug)
- 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 DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- 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 DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- 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
-
/*
* Wrappers for various ast_say_*() functions that call the full version
* of the same functions.
More information about the asterisk-commits
mailing list