Hi, all<br><br>&nbsp;&nbsp;&nbsp;&nbsp; I found that code in res_agi.c(version of 1.2.13) called fork() to create an AGI process, <br>however, fork() is not a safe function in Linux multi-thread environment because the child<br>process only hold one thread that made from a copy of the calling thread but inherit all the mutex
<br>or conditional variables including their state of the whole process.&nbsp; The child process doesn&#39;t<br>known the state of any mutex or conditional variable, It may fall into deadlock If it lock the mutex<br>before execv, For example, the following code fragment(in res_agi.c):
<br><br>&nbsp;&nbsp;&nbsp; pid = fork();<br>&nbsp;&nbsp;&nbsp; if (pid &lt; 0) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ast_log(LOG_WARNING, &quot;Failed to fork(): %s\n&quot;, strerror(errno));<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if (!pid) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Don&#39;t run AGI scripts with realtime priority -- it causes audio stutter */
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ast_set_priority(0);<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Redirect stdin and out, provide enhanced audio channel if desired */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dup2(fromast[0], STDIN_FILENO);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dup2(toast[1], STDOUT_FILENO);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (efd) {
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dup2(audio[0], STDERR_FILENO + 1);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; close(STDERR_FILENO + 1);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* unblock important signal handlers */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (sigfillset(&amp;signal_set) || pthread_sigmask(SIG_UNBLOCK, &amp;signal_set, NULL)) {
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ast_log(LOG_WARNING, &quot;unable to unblock signals for AGI script: %s\n&quot;, strerror(errno));<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Close everything but stdin/out/error */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (x=STDERR_FILENO + 2;x&lt;1024;x++) 
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; close(x);<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Execute script */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; execv(script, argv);<br><br>The ast_log() will lock a mutex if appropriate, but the mutex may be in locked state already.<br>Maybe we should use pthread_atfork() instead of fork() or never call some functions that hold mutex
<br>before execv() in child process.<br><br clear="all">Is there something that I missed?<br>-- <br>&nbsp;&nbsp;&nbsp;&nbsp;Regards