LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Embedded & Single-board computer (https://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/)
-   -   pipe and fork Trouble (https://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/pipe-and-fork-trouble-756859/)

ajb181 09-21-2009 05:15 PM

pipe and fork Trouble
 
Hi all. Im pretty new to linux but having some random problem with my app that has left me scratching my head for the last couple of days and was hoping you guys could help.

My app is using MPG321 to decode .mp3 files and i am having trouble killing the mpg forked task, both when i want to stop in the middle of a song(starting a new one) or starting a new song after completing last song.

I am piping the output of the MPG321 app to my application to get relevant track info but i'm pretty sure this is creating a problem when trying to destroy the forked process. If i do not attach the output to the pipe i don't get a problem.

Here is the relavent code

Code:

                                if (pipe(inst->_info_pipe))
                                {
                                        __SERVERDBG("Pipe failed");
                                        __EXCEPT(EXCEPTION_APPLICATION);
                                }

                                inst->_SongLen = 0;

                                frk_pid = fork ();

                                if (frk_pid == (pid_t) 0)
                                {
                                        dup2(inst->_info_pipe[1], 2);

                                        close(inst->_info_pipe[0]);

                                        setsid();
                                        execvp(exec_bin,cmd_ptr);

                                        close(inst->_info_pipe[1]);
                                        _exit(0);
                                }
                                else if (frk_pid < (pid_t) 0)
                                {

                                        __SERVERDBG("Pipe failed");
                                        inst->_main_thread = -1;

                                        inst->_current_state = UNDEFINED;
                                        __EXCEPT(EXCEPTION_APPLICATION);
                                }
                                else
                                {
                                        __SERVERDBG("fork parent %i", frk_pid);
                                        inst->_main_thread = frk_pid;

                //                        fcntl(inst->_info_pipe[0], F_SETFL, O_NONBLOCK);
                                        close(inst->_info_pipe[1]);

                                        inst->_current_state = PLAYING;
                                }
                        }
                }
                else if(inst->_info_pipe[0] != -1) // MP3 checks
                {
                        if(inst->_current_state == PLAYING )
                        {
                        // wont return from here till song is finished
                                do
                                {
                                        char* Tmp;
                                        int r = read(inst->_info_pipe[0], Tmp,50);

                                        if(r > 0)
                                        {
                                                char tmp1[r +1];
                                                memcpy(tmp1, Tmp, r);
                                                tmp1[r] = '\0';

                                                if(strncmp("ALSA", tmp1, 4) == 0)
                                                        __SERVERDBG("%s", tmp1);
                                        //        __SERVERDBG("%s", tmp1);

                                                inst->ParseOutput(Tmp, r);
                                        }
                                        else
                                        {
                                                os::sleep(20);
                                        }
                                }while(inst->_current_state == PLAYING);

this is my destroy process

Code:

void MP3Controller::StopPlayerApp()
{
        pid_t t;
        int reply;

        if(_main_thread == -1) // not thread running
                return;

        __SERVERDBG("Stopping Player %i", _main_thread);
        //Stop player
  int i = close(_info_pipe[0]); // shut pipe from MP3 app

        __SERVERDBG("Close pipe %i err %i", i , errno);

    os::sleep(100);

        reply = kill(-_main_thread, SIGTERM);

        __SERVERDBG("Stopping Player1 reply %i err %i", reply, errno);

        t = waitpid (_main_thread, NULL, WNOHANG);

        __SERVERDBG("waitpid %i err %i", t, errno);

        /*if (t != _main_thread && t != -1)
        {
                /* this one WILL HANG, so if someone sent a SIGSTOP to mpg123...
                t = waitpid (_main_thread, NULL, 0);

                __SERVERDBG("waitpid %i err %i", t, errno);
        }*/

        __SERVERDBG("Stopping Player2");
        _main_thread = -1;

        // Close pipes

    _info_pipe[0] = -1;
    _info_pipe[1] = -1;

        __SERVERDBG("Stopping Player3");
    FlushParser();

    __SERVERDBG("Stopping MP3");

}

i currently get an error from the waitpid() function. of 10 which is app dosent exist..?

when i do a ps in the terminal i see that the task has Zombied..(is that a word?). i can however start a new instance of mpg from command line without problem..

This was working on my pc but since porting to an embedded solution ... NO DEAL..

Thanks in advance for any help

Alex

padeen 10-01-2009 07:53 PM

First off, usual caveats, I haven't done anything with forking and sockets for a few years.

You are killing the process *group members* by killing them with -pid (-_main_thread), and you are waiting for a child process to change state. Is _main_thread a group pid or a process pid? I think it's a process id. What other process group members are there for you to want to kill them all, instead of just killing the child?

jiml8 10-01-2009 09:04 PM

You are killing the main thread, but not permitting the main thread to terminate the child. Of course you are getting a zombie process.

You need to alter your code to put a signal handler in the main process. When the terminate signal comes through, the main process sighandler catches the signal and does something - maybe it sets a flag. Your main thread is in a loop; at the bottom of each pass through the loop, have it check that flag. When it sees the flag is set, it cleans itself up, kills the child process, and exits.


All times are GMT -5. The time now is 08:28 PM.