Fix deadlock potential with ast_set_hangupsource() calls.
[asterisk/asterisk.git] / channels / chan_iax2.c
index ade8438..467cdb4 100644 (file)
@@ -9898,11 +9898,20 @@ static void set_hangup_source_and_cause(int callno, unsigned char causecode)
 {
        iax2_lock_owner(callno);
        if (iaxs[callno] && iaxs[callno]->owner) {
+               struct ast_channel *owner;
+               const char *name;
+
+               owner = iaxs[callno]->owner;
                if (causecode) {
-                       ast_channel_hangupcause_set(iaxs[callno]->owner, causecode);
+                       ast_channel_hangupcause_set(owner, causecode);
                }
-               ast_set_hangupsource(iaxs[callno]->owner, ast_channel_name(iaxs[callno]->owner), 0);
-               ast_channel_unlock(iaxs[callno]->owner);
+               name = ast_strdupa(ast_channel_name(owner));
+               ast_channel_ref(owner);
+               ast_channel_unlock(owner);
+               ast_mutex_unlock(&iaxsl[callno]);
+               ast_set_hangupsource(owner, name, 0);
+               ast_channel_unref(owner);
+               ast_mutex_lock(&iaxsl[callno]);
        }
 }