[asterisk-dev] fork or pthread_atfork

Yuan Qin yuan007qin at gmail.com
Fri Apr 6 08:04:27 MST 2007

Hi, all

     I found that code in res_agi.c(version of 1.2.13) called fork() to
create an AGI process,
however, fork() is not a safe function in Linux multi-thread environment
because the child
process only hold one thread that made from a copy of the calling thread but
inherit all the mutex
or conditional variables including their state of the whole process.  The
child process doesn't
known the state of any mutex or conditional variable, It may fall into
deadlock If it lock the mutex
before execv, For example, the following code fragment(in res_agi.c):

    pid = fork();
    if (pid < 0) {
        ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
        return -1;
    if (!pid) {
        /* Don't run AGI scripts with realtime priority -- it causes audio
stutter */

        /* Redirect stdin and out, provide enhanced audio channel if desired
        dup2(fromast[0], STDIN_FILENO);
        dup2(toast[1], STDOUT_FILENO);
        if (efd) {
            dup2(audio[0], STDERR_FILENO + 1);
        } else {
            close(STDERR_FILENO + 1);

        /* unblock important signal handlers */
        if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK,
&signal_set, NULL)) {
            ast_log(LOG_WARNING, "unable to unblock signals for AGI script:
%s\n", strerror(errno));

        /* Close everything but stdin/out/error */
        for (x=STDERR_FILENO + 2;x<1024;x++)

        /* Execute script */
        execv(script, argv);

The ast_log() will lock a mutex if appropriate, but the mutex may be in
locked state already.
Maybe we should use pthread_atfork() instead of fork() or never call some
functions that hold mutex
before execv() in child process.

Is there something that I missed?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digium.com/pipermail/asterisk-dev/attachments/20070406/57e8ba8f/attachment-0001.htm

More information about the asterisk-dev mailing list