DaanDeMeyer / reproc

A cross-platform (C99/C++11) process library
MIT License
552 stars 65 forks source link

[Multithreading] "Interrupted system call" on read call with Xcode #37

Closed sy6sy2 closed 4 years ago

sy6sy2 commented 4 years ago

Hi,

I am still playing with reproc and multithreading by I think that I need your help. I will try to explain my issue with a minimal pseudo code.

Context: I use reproc to communicate with multiple SMT solver processes.

This is my Solver class:

class Solver
{
   int m_solver_id;
   reproc::process m_solver_process;
};

During my program initialization I start 2 solver processes like that:

std::vector<Solver *> solvers;
for(int i = 0 ; i < 2 ; i++)
{
    Solver* solver = new Solver();
    solver->m_solver_id = i;
    solver->m_solver_process = reproc::process();
    solver->m_solver_process.start({"cvc4"});
}

From here, my 2 solver processes are ready and are running.

Also, some times I need to restart one solver process with this function:

void restartSolver(Solver* solver)
{
    reproc::stop_actions process_stop_actions = {
        { reproc::stop::terminate, reproc::milliseconds(100)},
        { reproc::stop::kill, reproc::milliseconds(100)},
        {}
      };
    solver->m_process.stop(process_stop_actions);
    solver->m_solver_process = reproc::process();
    solver->m_solver_process.start({"cvc4"});
    return;
}

Now, during my program workflow, I have multiple thread that read/write on solvers stdin and stdout.

BUT, if from thread n°0 I am performing read/write operations on solver n°0, and if at the same time thread n°1 call restartSolver() on solver n°2, then I get a Operation not permitted error on the solver n°0 poll call.

Do you know why?

Thank you for your help.

Edit: Currently using 11.0.2 reprocxx version. I will try with 12.0.0 soon.

Edit: I am now on 12.1.0, so I remove the poll line of my read fonction because I want a blocking read. Now I get this error message Interrupted system call on the read. Also, I notice that I only get this error when I run my project from Xcode but not from my terminal...

DaanDeMeyer commented 4 years ago

This might be similar to #8. The returned error message means the EINTR error was returned by a system call. This might mean the XCode debugger is doing something with the signal handling. Can you see if adding signal(SIGCHLD, SIG_IGN); before starting the solvers changes anything?

I'm trying to think of a way to reproduce this on my end since I don't have a mac but I think if it only triggers when running via XCode then it's going to be hard to reproduce without access to a mac.

sy6sy2 commented 4 years ago

Thank you for your answer!

With signal(SIGCHLD, SIG_IGN);, during the restartSolver function call; I am stuck forever in:

reproc_stop (line 136 of reproc.cpp) --> reproc_wait (line 528 of reproc.c) --> reproc_wait (line 460 of reproc.c) --> process_wait (line 452 of process.posix.c) --> waitpid

Maybe this answer can help? https://stackoverflow.com/a/45472920/6166580

DaanDeMeyer commented 4 years ago

Does the same issue still happen when running only a single thread with a single solver process?

DaanDeMeyer commented 4 years ago

Two more possible solutions:

sy6sy2 commented 4 years ago

I don't know why but I am not able to reproduce the issue anymore on Xcode. Thank you for your research. If the issue come back again I will give you more information. Fell free to close this issue if needed, and if you need a test with a specific code I can do it.

Thank you.

DaanDeMeyer commented 4 years ago

Feel free to reopen the issue if you encounter the problem again.