All pastes #25181 Raw Edit

Stuff

public text v1 · immutable
#25181 ·published 2005-10-11 01:27 UTC
rendered paste body
static struct opbx_channel *channel_find_locked(const struct opbx_channel *prev,
                                               const char *name, const int namelen,
                                               const char *context, const char *exten)
{
        const char *msg = prev ? "deadlock" : "initial deadlock";
        int retries, done;
        struct opbx_channel *c;

        for (retries = 0; retries < 10; retries++) {
                opbx_mutex_lock(&chlock);
                for (c = channels; c; c = c->next) {
                        if (!prev) {
                                /* want head of list */
                                if (!name && !exten)
                                        break;
                                if (name) {
                                        /* want match by full name */
                                        if (!namelen) {
                                                if (!strcasecmp(c->name, name))
                                                        break;
                                                else
                                                        continue;
                                        }
                                        /* want match by name prefix */
                                        if (!strncasecmp(c->name, name, namelen))
                                                break;
                                } else if (exten) {
                                        /* want match by context and exten */
                                        if (context && (strcasecmp(c->context, context) &&
                                                        strcasecmp(c->macrocontext, context)))
                                                continue;
                                        /* match by exten */
                                        if (strcasecmp(c->exten, exten) &&
                                            strcasecmp(c->macroexten, exten))
                                                continue;
                                        else
                                                break;
                                }
                        } else if (c == prev) { /* found, return c->next */
                                c = c->next;
                                break;
                        }
                }
                /* exit if chan not found or mutex acquired successfully */
                done = (c == NULL) || (opbx_mutex_trylock(&c->lock) == 0);
                /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
                if (!done && c)
                        opbx_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name);
                opbx_mutex_unlock(&chlock);
                if (done)
                        return c;
                usleep(1);
        }
        /*
         * c is surely not null, but we don't have the lock so cannot
         * access c->name
         */
        opbx_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n",
                msg, c, retries);

        return NULL;
}