--- src/gdl2gdl.cpp.orig 2024-11-02 17:32:21 UTC +++ src/gdl2gdl.cpp @@ -29,6 +29,7 @@ #include /* shared memory and mmap() */ #include #include +#include #include "dinterpreter.hpp" static bool atexit_already_done = false; @@ -103,13 +104,29 @@ void g2gAsynchronousReturnTrap() { } void g2gAsynchronousReturnTrap() { - while (g2gMap.size() > 0) { - for (g2gMapIter it = g2gMap.begin(); it != g2gMap.end(); ++it) { - if ( (*it).second.status==1 && (*it).second.nowait ) gdl_ipc_read_client_nowait((*it).first); - } - usleep (10000); + while (!g2gMap.empty()) { + for (auto g2gMapIter = g2gMap.cbegin(); g2gMapIter != g2gMap.cend();) { + if ((*g2gMapIter).second.status == 1 && (*g2gMapIter).second.nowait) { + gdl_ipc_read_client_nowait((*g2gMapIter).first); + } + // contrib by @jkohnert - to be used should a concurrency problem with the spawn command appear. + // At the moment better to keep initial version (GD). + // // we need to take care of our children, use a no-hang wait call to check the pid + // int status = -1; + // if (waitpid((*g2gMapIter).first, &status, WUNTRACED | WCONTINUED | WNOHANG) == -1) { + // // we're out of luck, wait returns an error, so break the loop and exit + // std::cerr << "g2gAsynchronousReturnTrap exiting" << std::endl; + // break; + // } + // // remove stopped children from the map + // if (WIFEXITED(status) || WIFSIGNALED(status)) + // g2gMap.erase(g2gMapIter++); + // // we need to manually count here, since we're modifying the map in the loop + // else + ++g2gMapIter; + } + usleep(10000); // GD: should replace usleep by nanosleep everywhere ! } -// std::cerr<<"g2gAsynchronousReturnTrap exiting"<(subprocess_pid,params)); g2gMap.at(subprocess_pid).MessageChannelHandle=id; // insure communication with child is OK waiting for a status change