This is not good to take a global lock and jump into the asterisk code. It looks like following situation appears: while held iflock and waiting for channels->lock in asterisk other thread which already held channels->lock jumps jumps some where iflock is required.
This commit is contained in:
parent
50df20964f
commit
37f2ff6580
12
chan_capi.c
12
chan_capi.c
|
@ -216,7 +216,7 @@ static char global_mohinterpret[MAX_MUSICCLASS] = "default";
|
|||
#endif
|
||||
|
||||
/* local prototypes */
|
||||
#define CC_B_INTERFACE_NOT_FREE(__x__) (((__x__)->used) || \
|
||||
#define CC_B_INTERFACE_NOT_FREE(__x__) (((__x__)->used) || ((__x__)->reserved) || \
|
||||
((__x__)->channeltype != CAPI_CHANNELTYPE_B) || \
|
||||
(capi_controllers[(__x__)->controller]->nfreebchannels < capi_controllers[(__x__)->controller]->nfreebchannelsHardThr))
|
||||
|
||||
|
@ -1212,6 +1212,7 @@ static void interface_cleanup(struct capi_pvt *i)
|
|||
i->peer = NULL;
|
||||
i->owner = NULL;
|
||||
i->used = NULL;
|
||||
i->reserved = 0;
|
||||
|
||||
if (i->channeltype == CAPI_CHANNELTYPE_NULL) {
|
||||
capi_interface_task(i, CAPI_INTERFACE_TASK_NULLIFREMOVE);
|
||||
|
@ -2366,6 +2367,9 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state, const char *l
|
|||
tmp = ast_channel_alloc(0);
|
||||
#endif
|
||||
|
||||
cc_mutex_lock(&iflock);
|
||||
i->reserved = 0;
|
||||
|
||||
if (tmp == NULL) {
|
||||
cc_log(LOG_ERROR, "Unable to allocate channel!\n");
|
||||
return NULL;
|
||||
|
@ -2660,6 +2664,8 @@ pbx_capi_request(const char *type, int format, void *data, int *cause)
|
|||
found_best_channel:
|
||||
/* when we come here, we found a free controller match */
|
||||
cc_copy_string(i->dnid, dest, sizeof(i->dnid));
|
||||
i->reserved = 1;
|
||||
cc_mutex_unlock(&iflock);
|
||||
tmp = capi_new(i, AST_STATE_RESERVED,
|
||||
#ifdef CC_AST_HAS_REQUEST_REQUESTOR
|
||||
requestor ? requestor->linkedid : NULL
|
||||
|
@ -5356,7 +5362,7 @@ static void capidev_handle_connect_indication(
|
|||
/* well...somebody is calling us. let's set up a channel */
|
||||
cc_mutex_lock(&iflock);
|
||||
for (i = capi_iflist; i; i = i->next) {
|
||||
if (i->used) {
|
||||
if (i->used || i->reserved) {
|
||||
/* is already used */
|
||||
continue;
|
||||
}
|
||||
|
@ -5413,6 +5419,8 @@ static void capidev_handle_connect_indication(
|
|||
i->MessageNumber = HEADER_MSGNUM(CMSG);
|
||||
i->cid_ton = callernplan;
|
||||
|
||||
i->reserved = 1;
|
||||
cc_mutex_unlock(&iflock);
|
||||
capi_new(i, AST_STATE_DOWN, NULL);
|
||||
if (i->isdnmode == CAPI_ISDNMODE_DID) {
|
||||
i->state = CAPI_STATE_DID;
|
||||
|
|
|
@ -393,6 +393,8 @@ struct capi_pvt {
|
|||
struct ast_channel *owner;
|
||||
/*! Channel who called us, possibly NULL */
|
||||
struct ast_channel *peer;
|
||||
/*! Set if structure is reserved */
|
||||
volatile int reserved;
|
||||
|
||||
/* capi message number */
|
||||
_cword MessageNumber;
|
||||
|
|
Loading…
Reference in New Issue