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:
MelwareDE 2012-04-11 09:45:19 +00:00
parent 50df20964f
commit 37f2ff6580
2 changed files with 12 additions and 2 deletions

View File

@ -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;

View File

@ -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;