This mod via bug 7531
[asterisk/asterisk.git] / main / channel.c
index 6a5ecae..ace4a41 100644 (file)
@@ -29,6 +29,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <sys/time.h>
 #include <signal.h>
@@ -100,7 +101,7 @@ static int uniqueint = 0;
 
 unsigned long global_fin = 0, global_fout = 0;
 
-AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
+AST_THREADSTORAGE(state2str_threadbuf);
 #define STATE2STR_BUFSIZE   32
 
 /* XXX 100ms ... this won't work with wideband support */
@@ -289,19 +290,19 @@ static char *complete_channeltypes(const char *line, const char *word, int pos,
 }
 
 static char show_channeltypes_usage[] =
-"Usage: channeltype list\n"
+"Usage: core show channeltypes\n"
 "       Lists available channel types registered in your Asterisk server.\n";
 
 static char show_channeltype_usage[] =
-"Usage: channeltype show <name>\n"
+"Usage: core show channeltype <name>\n"
 "      Show details about the specified channel type, <name>.\n";
 
 static struct ast_cli_entry cli_channel[] = {
-       { { "channeltype", "list", NULL },
+       { { "core", "show", "channeltypes", NULL },
        show_channeltypes, "List available channel types",
        show_channeltypes_usage },
 
-       { { "channeltype", "show", NULL },
+       { { "core", "show", "channeltype", NULL },
        show_channeltype, "Give more details on that channel type",
        show_channeltype_usage, complete_channeltypes },
 };
@@ -330,6 +331,21 @@ static int ast_check_hangup_locked(struct ast_channel *chan)
        return res;
 }
 
+/*! \brief printf the string into a correctly sized mallocd buffer, and return the buffer */
+char *ast_safe_string_alloc(const char *fmt, ...)
+{
+       char *b2,buf[1];
+       int len;
+
+       va_list args;
+       va_start(args, fmt);
+       len = vsnprintf(buf, 1, fmt, args);
+       b2 = ast_malloc(len+1);
+       vsnprintf(b2, len+1,  fmt, args);
+       va_end(args);
+       return b2;
+}
+
 /*! \brief Initiate system shutdown */
 void ast_begin_shutdown(int hangup)
 {
@@ -608,12 +624,13 @@ static const struct ast_channel_tech null_tech = {
 };
 
 /*! \brief Create a new channel structure */
-struct ast_channel *ast_channel_alloc(int needqueue)
+struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *name_fmt, ...)
 {
        struct ast_channel *tmp;
        int x;
        int flags;
        struct varshead *headp;
+       va_list ap1, ap2;
 
        /* If shutting down, don't allocate any new channels */
        if (shutting_down) {
@@ -654,7 +671,7 @@ struct ast_channel *ast_channel_alloc(int needqueue)
        if (needqueue) {
                if (pipe(tmp->alertpipe)) {
                        ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
-                       ast_string_field_free_all(tmp);
+                       ast_string_field_free_pools(tmp);
                        free(tmp);
                        return NULL;
                } else {
@@ -671,10 +688,10 @@ struct ast_channel *ast_channel_alloc(int needqueue)
        /* And timing pipe */
        tmp->fds[AST_TIMING_FD] = tmp->timingfd;
        ast_string_field_set(tmp, name, "**Unknown**");
-       
+
        /* Initial state */
-       tmp->_state = AST_STATE_DOWN;
-       
+       tmp->_state = state;
+
        tmp->streamid = -1;
        
        tmp->fin = global_fin;
@@ -688,6 +705,37 @@ struct ast_channel *ast_channel_alloc(int needqueue)
                        (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
        }
 
+       if (!ast_strlen_zero(name_fmt)) {
+               /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
+                * And they all use slightly different formats for their name string.
+                * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
+                * This means, that the stringfields must have a routine that takes the va_lists directly, and 
+                * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
+                * This new function was written so this can be accomplished.
+                */
+               va_start(ap1, name_fmt);
+               va_start(ap2, name_fmt);
+               ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
+               va_end(ap1);
+               va_end(ap2);
+
+               /* and now, since the channel structure is built, and has its name, let's call the
+                * manager event generator with this Newchannel event. This is the proper and correct
+                * place to make this call, but you sure do have to pass a lot of data into this func
+                * to do it here!
+                */
+               manager_event(EVENT_FLAG_CALL, "Newchannel",
+                             "Channel: %s\r\n"
+                             "State: %s\r\n"
+                             "CallerIDNum: %s\r\n"
+                             "CallerIDName: %s\r\n"
+                             "Uniqueid: %s\r\n",
+                             tmp->name, ast_state2str(state),
+                             S_OR(cid_num, "<unknown>"),
+                             S_OR(cid_name, "<unknown>"),
+                             tmp->uniqueid);
+       }
+       
        headp = &tmp->varshead;
        AST_LIST_HEAD_INIT_NOLOCK(headp);
        
@@ -745,7 +793,8 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
                        ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
                        CRASH;
                } else {
-                       ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
                        ast_frfree(f);
                        ast_channel_unlock(chan);
                        return 0;
@@ -881,8 +930,10 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
                /* exit if chan not found or mutex acquired successfully */
                /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
                done = c == NULL || ast_channel_trylock(c) == 0;
-               if (!done)
-                       ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
+               if (!done) {
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
+               }
                AST_LIST_UNLOCK(&channels);
                if (done)
                        return c;
@@ -892,8 +943,9 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
         * c is surely not null, but we don't have the lock so cannot
         * access c->name
         */
-       ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n",
-               c, retries);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n",
+                       c, retries);
 
        return NULL;
 }
@@ -1051,7 +1103,7 @@ void ast_channel_free(struct ast_channel *chan)
        /* Destroy the jitterbuffer */
        ast_jb_destroy(chan);
 
-       ast_string_field_free_all(chan);
+       ast_string_field_free_pools(chan);
        free(chan);
        AST_LIST_UNLOCK(&channels);
 
@@ -1202,8 +1254,9 @@ int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
                ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
        }
 
-       ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
-               spy->type, chan->name);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
+                       spy->type, chan->name);
 
        return 0;
 }
@@ -1238,7 +1291,8 @@ static void spy_detach(struct ast_channel_spy *spy, struct ast_channel *chan)
        }
 
        /* Print it out while we still have a lock so the structure can't go away (if signalled above) */
-       ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
 
        ast_mutex_unlock(&spy->lock);
 
@@ -1383,8 +1437,9 @@ static void queue_frame_to_spies(struct ast_channel *chan, struct ast_frame *f,
                                        trans->path = NULL;
                                }
                                if (!trans->path) {
-                                       ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
-                                               ast_getformatname(f->subclass), chan->name);
+                                       if (option_debug)
+                                               ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
+                                                       ast_getformatname(f->subclass), chan->name);
                                        if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
                                                ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
                                                        ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
@@ -1628,7 +1683,8 @@ static int generator_force(void *data)
        res = generate(chan, tmp, 0, 160);
        chan->generatordata = tmp;
        if (res) {
-               ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
                ast_deactivate_generator(chan);
        }
        return 0;
@@ -1847,7 +1903,8 @@ int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data),
                        samples = 0;
                        data = 0;
                }
-               ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
                res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
                c->timingfunc = func;
                c->timingdata = data;
@@ -2052,11 +2109,13 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
                case AST_FRAME_CONTROL:
                        if (f->subclass == AST_CONTROL_ANSWER) {
                                if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
-                                       ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
+                                       if (option_debug)
+                                               ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
                                        ast_frfree(f);
                                        f = &ast_null_frame;
                                } else if (prestate == AST_STATE_UP) {
-                                       ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
+                                       if (option_debug)
+                                               ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
                                        ast_frfree(f);
                                        f = &ast_null_frame;
                                } else {
@@ -2266,7 +2325,8 @@ int ast_indicate_data(struct ast_channel *chan, int condition, const void *data,
                                break;
                        }
                        if (ts && ts->data[0]) {
-                               ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
                                ast_playtones_start(chan,0,ts->data, 1);
                                res = 0;
                        } else if (condition == AST_CONTROL_PROGRESS) {
@@ -2379,7 +2439,8 @@ int ast_senddigit_begin(struct ast_channel *chan, char digit)
                        ast_playtones_start(chan, 0, dtmf_tones[15], 0);
                else {
                        /* not handled */
-                       ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
                }
        }
 
@@ -2415,7 +2476,8 @@ int ast_prod(struct ast_channel *chan)
 
        /* Send an empty audio frame to get things moving */
        if (chan->_state != AST_STATE_UP) {
-               ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
                a.subclass = chan->rawwriteformat;
                a.data = nothing + AST_FRIENDLY_OFFSET;
                a.src = "ast_prod";
@@ -2601,7 +2663,10 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                res = 0;
                break;
        default:
-               res = chan->tech->write(chan, f);
+               /* At this point, fr is the incoming frame and f is NULL.  Channels do
+                * not expect to get NULL as a frame pointer and will segfault.  Hence,
+                * we output the original frame passed in. */
+               res = chan->tech->write(chan, fr);
                break;
        }
 
@@ -2841,19 +2906,8 @@ struct ast_channel *ast_request(const char *type, int format, void *data, int *c
                
                if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
                        return NULL;
-
-               if (c->_state == AST_STATE_DOWN) {
-                       manager_event(EVENT_FLAG_CALL, "Newchannel",
-                                     "Channel: %s\r\n"
-                                     "State: %s\r\n"
-                                     "CallerIDNum: %s\r\n"
-                                     "CallerIDName: %s\r\n"
-                                     "Uniqueid: %s\r\n",
-                                     c->name, ast_state2str(c->_state),
-                                     S_OR(c->cid.cid_num, "<unknown>"),
-                                     S_OR(c->cid.cid_name, "<unknown>"),
-                                     c->uniqueid);
-               }
+               
+               /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
                return c;
        }
 
@@ -3066,8 +3120,9 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo
                return -1;
        }
 
-       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
-               clone->name, original->name);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
+                       clone->name, original->name);
        if (original->masq) {
                ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
                        original->masq->name, original->name);
@@ -3079,7 +3134,8 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo
                clone->masqr = original;
                ast_queue_frame(original, &ast_null_frame);
                ast_queue_frame(clone, &ast_null_frame);
-               ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
                res = 0;
        }
 
@@ -3199,6 +3255,9 @@ int ast_do_masquerade(struct ast_channel *original)
                ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
                        clone->name, clone->_state, original->name, original->_state);
 
+       manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n",
+                     clone->name, ast_state2str(clone->_state), original->name, ast_state2str(original->_state));
+
        /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
           the clone channel into the original channel.  Start by killing off the original
           channel's backend.   I'm not sure we're going to keep this function, because
@@ -3438,7 +3497,8 @@ int ast_do_masquerade(struct ast_channel *original)
                        );
                ast_channel_free(clone);
        } else {
-               ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
                ast_set_flag(clone, AST_FLAG_ZOMBIE);
                ast_queue_frame(clone, &ast_null_frame);
                ast_channel_unlock(clone);
@@ -3495,8 +3555,9 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
 
        chan->_state = state;
        ast_device_state_changed_literal(chan->name);
+       /* setstate used to conditionally report Newchannel; this is no more */
        manager_event(EVENT_FLAG_CALL,
-                     (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
+                     "Newstate",
                      "Channel: %s\r\n"
                      "State: %s\r\n"
                      "CallerIDNum: %s\r\n"
@@ -3625,7 +3686,8 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
                if (!f) {
                        *fo = NULL;
                        *rc = who;
-                       ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
                        break;
                }
 
@@ -3647,7 +3709,8 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
                                *fo = f;
                                *rc = who;
                                bridge_exit = 1;
-                               ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
                                break;
                        }
                        if (bridge_exit)
@@ -3669,9 +3732,10 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
                                f->frametype == AST_FRAME_DTMF_BEGIN)) {
                                *fo = f;
                                *rc = who;
-                               ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
-                                       f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
-                                       who->name);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
+                                               f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
+                                               who->name);
                                break;
                        }
                        /* Write immediately frames, not passed through jb */
@@ -3818,7 +3882,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                                                bridge_playfile(c1, c0, config->warning_sound, t);
                                }
                                if (config->warning_freq) {
-                                       nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
+
+                                       if (time_left_ms > (config->warning_freq + 5000)) {
+                                               nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
+                                       }
+                                                               
                                } else
                                        nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
                        }
@@ -3831,7 +3899,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                                c1->_softhangup = 0;
                        c0->_bridge = c1;
                        c1->_bridge = c0;
-                       ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
                        continue;
                }
                
@@ -3842,12 +3911,13 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                        if (who)
                                *rc = who;
                        res = 0;
-                       ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
-                               c0->name, c1->name,
-                               ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
-                               ast_check_hangup(c0) ? "Yes" : "No",
-                               ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
-                               ast_check_hangup(c1) ? "Yes" : "No");
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
+                                       c0->name, c1->name,
+                                       ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
+                                       ast_check_hangup(c0) ? "Yes" : "No",
+                                       ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
+                                       ast_check_hangup(c1) ? "Yes" : "No");
                        break;
                }
 
@@ -3870,7 +3940,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                                              "CallerID1: %s\r\n"
                                              "CallerID2: %s\r\n",
                                              c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
-                               ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
 
                                ast_clear_flag(c0, AST_FLAG_NBRIDGE);
                                ast_clear_flag(c1, AST_FLAG_NBRIDGE);
@@ -3936,7 +4007,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                      "CallerID1: %s\r\n"
                      "CallerID2: %s\r\n",
                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
-       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
 
        return res;
 }
@@ -4461,30 +4533,26 @@ int ast_channel_unlock(struct ast_channel *chan)
                ast_log(LOG_DEBUG, "::::==== Unlocking AST channel %s\n", chan->name);
        
        if (!chan) {
-               ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n");
+               if (option_debug)
+                       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.__data.__count))
-#else
-               if ((count = chan->lock.__data.__count))
-#endif
-                       ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count);
+               int count = 0;
+               if ((count = chan->lock.reentrancy))
+                       if (option_debug)
+                               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 (option_debug)
+                               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 (option_debug)
+                                       ast_log(LOG_DEBUG, "::::==== Channel %s had no lock by this thread. Failed unlocking\n", chan->name);
                        }
                }
                if (res == EPERM) {
@@ -4508,17 +4576,15 @@ int ast_channel_lock(struct ast_channel *chan)
        res = ast_mutex_lock(&chan->lock);
 
        if (option_debug > 3) {
-#ifdef __linux__
-               int count = 0;
 #ifdef DEBUG_THREADS
-               if ((count = chan->lock.mutex.__data.__count))
-#else
-               if ((count = chan->lock.__data.__count))
-#endif
-                       ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
+               int count = 0;
+               if ((count = chan->lock.reentrancy))
+                       if (option_debug)
+                               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 (option_debug)
+                               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)
@@ -4544,17 +4610,15 @@ int ast_channel_trylock(struct ast_channel *chan)
        res = ast_mutex_trylock(&chan->lock);
 
        if (option_debug > 2) {
-#ifdef __linux__
-               int count = 0;
 #ifdef DEBUG_THREADS
-               if ((count = chan->lock.mutex.__data.__count))
-#else
-               if ((count = chan->lock.__data.__count))
-#endif
-                       ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
+               int count = 0;
+               if ((count = chan->lock.reentrancy))
+                       if (option_debug)
+                               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 (option_debug)
+                               ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
                if (res == EBUSY) {
                        /* We failed to lock */
                        if (option_debug > 2)