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
"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);