Hi, all<br><br> 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. The child process doesn'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> pid = fork();<br> if (pid < 0) {<br> ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));<br> return -1;<br> }<br> if (!pid) {<br> /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
<br> ast_set_priority(0);<br><br> /* Redirect stdin and out, provide enhanced audio channel if desired */<br> dup2(fromast[0], STDIN_FILENO);<br> dup2(toast[1], STDOUT_FILENO);<br> if (efd) {
<br> dup2(audio[0], STDERR_FILENO + 1);<br> } else {<br> close(STDERR_FILENO + 1);<br> }<br> <br> /* unblock important signal handlers */<br> if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
<br> ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));<br> exit(1);<br> }<br><br> /* Close everything but stdin/out/error */<br> for (x=STDERR_FILENO + 2;x<1024;x++)
<br> close(x);<br><br> /* Execute script */<br> 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> Regards