stasis/app: don't lock an app before a call to send
Calling 'app_send' eventually calls the app's message handler. It's possible for a handler to obtain a lock on another object, and then need/want to lock the app object. If the caller of 'app_send' locks the app object prior to calling then there's a potential for a deadlock, if another thread calls 'app_send' without locking. This patch makes it so 'app_send' is not called with the app object locked in the section of code doing such. ASTERISK-28423 #close Change-Id: I6767c6d0933c7db1b984018966eefca4c0638a27
This commit is contained in:
parent
313189aae2
commit
cce2b0da95
|
@ -1126,8 +1126,23 @@ void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
|
|||
"timestamp", ast_json_timeval(ast_tvnow(), NULL),
|
||||
"application", app->name);
|
||||
if (msg) {
|
||||
/*
|
||||
* The app must be unlocked before calling 'send' since a handler may
|
||||
* subsequently attempt to grab the app lock after first obtaining a
|
||||
* lock for another object, thus causing a deadlock.
|
||||
*/
|
||||
ao2_unlock(app);
|
||||
app_send(app, msg);
|
||||
ao2_lock(app);
|
||||
ast_json_unref(msg);
|
||||
if (!app->handler) {
|
||||
/*
|
||||
* If the handler disappeared then the app was deactivated. In that
|
||||
* case don't replace. Re-activation will reset the handler later.
|
||||
*/
|
||||
ao2_unlock(app);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_verb(1, "Activating Stasis app '%s'\n", app->name);
|
||||
|
|
Loading…
Reference in New Issue