Skip to content

Commit b0010ae

Browse files
Fix #91 Play to conference scenario has a race condition that causes a segfault
1 parent 5b90114 commit b0010ae

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
diff --exclude='*.xml' --exclude='*.o.d' --exclude=.project --exclude=.cproject -Naur asterisk-base-11.3.0/main/bridging.c asterisk-11.3.0/main/bridging.c
2+
--- asterisk-base-11.3.0/main/bridging.c 2023-01-06 10:20:26.660000000 -0500
3+
+++ asterisk-11.3.0/main/bridging.c 2023-01-06 10:27:35.480000000 -0500
4+
@@ -972,23 +972,27 @@
5+
cap = ast_format_cap_destroy(cap);
6+
7+
ast_channel_internal_bridge_set(playback_chan, bridge_channel->bridge);
8+
+ ast_debug(1, "Playback channel created %p\n", playback_chan);
9+
10+
if (ast_call(playback_chan, "pseudo", 0)) {
11+
+ ast_debug(1, "Hangup playback channel %p\n", playback_chan);
12+
ast_hangup(playback_chan);
13+
playback_chan = NULL;
14+
pthread_exit(0);
15+
}
16+
17+
underlying_channel = ast_channel_tech(playback_chan)->bridged_channel(playback_chan, NULL);
18+
+ ast_debug(1, "Underlying channel created %p\n", underlying_channel);
19+
20+
ast_stopstream(playback_chan);
21+
22+
+
23+
if (!ast_strlen_zero(ast_channel_conf_playann(bridge_channel->chan))) {
24+
res = ast_streamfile(playback_chan, ast_channel_conf_playann(bridge_channel->chan), ast_channel_language(playback_chan));
25+
if (!res) {
26+
while(ast_channel_stream(playback_chan))
27+
{
28+
- if (!bridge_channel->chan || ast_test_flag(ast_channel_inoflags(bridge_channel->chan), CONF_STOP_PLAY))
29+
+ if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT || !bridge_channel->chan || ast_test_flag(ast_channel_inoflags(bridge_channel->chan), CONF_STOP_PLAY))
30+
{
31+
ast_stopstream(playback_chan);
32+
break;
33+
@@ -1038,17 +1042,33 @@
34+
}
35+
}
36+
37+
- ao2_lock(bridge_channel->bridge);
38+
- ast_clear_flag(ast_channel_inoflags(bridge_channel->chan), CONF_STOP_PLAY);
39+
- ast_clear_flag(ast_channel_inoflags(bridge_channel->chan), CONF_PLAYING);
40+
- ast_set_flag(ast_channel_inoflags(bridge_channel->chan), CONF_PLAY_ENDED);
41+
- ao2_unlock(bridge_channel->bridge);
42+
-
43+
- if(bridge_channel->bridge && underlying_channel)
44+
- {
45+
- ast_bridge_depart(bridge_channel->bridge, underlying_channel);
46+
+ if(bridge_channel && bridge_channel->bridge && (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT || bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_END)){
47+
+ if(!ao2_lock(bridge_channel->bridge))
48+
+ {
49+
+ if(bridge_channel->chan && !ast_channel_lock(bridge_channel->chan)){
50+
+ ast_clear_flag(ast_channel_inoflags(bridge_channel->chan), CONF_STOP_PLAY);
51+
+ ast_clear_flag(ast_channel_inoflags(bridge_channel->chan), CONF_PLAYING);
52+
+ ast_set_flag(ast_channel_inoflags(bridge_channel->chan), CONF_PLAY_ENDED);
53+
+ ast_channel_unlock(bridge_channel->chan);
54+
+ }
55+
+ ao2_unlock(bridge_channel->bridge);
56+
+ }
57+
+
58+
+ if(bridge_channel && bridge_channel->bridge && underlying_channel)
59+
+ {
60+
+ ast_debug(1, "Depart underlying channel %p from bridge %p\n", underlying_channel, bridge_channel);
61+
+ ast_bridge_depart(bridge_channel->bridge, underlying_channel);
62+
+ }
63+
+ }
64+
+
65+
+ if(playback_chan){
66+
+ ast_debug(1, "Hangup playback channel %p\n", playback_chan);
67+
ast_hangup(playback_chan);
68+
playback_chan = NULL;
69+
+ }
70+
+
71+
+ if(underlying_channel){
72+
+ ast_debug(1, "Hangup underlying channel %p\n", underlying_channel);
73+
ast_hangup(underlying_channel);
74+
underlying_channel = NULL;
75+
}

0 commit comments

Comments
 (0)