On Fri, Sep 21, 2018 at 05:26:27PM -0400, Mark H Weaver wrote: > Hi, > > Can you describe in more detail the behavior you are seeing? What > messages do you see on stderr from your 'dump' calls when it gets stuck? > What state is the atomic box left in? > > I see a couple of problems with the code below: > > * Two threads write concurrently to the same port, namely > (current-error-port). You should use thread synchronization to ensure > that operations to a given port are serialized. > > * There's a race condition when the atomic box is in the #:accepted > state. If the main thread finds the box in that state, it changes the > state to #:need-to-sleep, which will apparently cause the other thread > to sleep again. > > I'm not sure if these problems could explain what you're seeing. > > Regards, > Mark >
The code is supposed to model the following behaviour. The main thread tracks some events (in the example: the end of (sleep 3)). If one or multiple events occurred some long-lasting external command should be executed. Long-lasting means that multiple events may occur during execution. To perform that the main thread should: 1. either to run new work thread (sleep-loop procedure), which will call (system* ...); 2. or to communicate the fact of events occurrences to the work thread, which is supposed to detect this and just repeat the command. If multiple events have occurred during command execution the command should be re-executed only once. The event occurrence is communicated through simple protocol with three states: #:nothing-to-do < #:accepted < #:need-to-sleep. The main thread pulls state up, and work thread pulls it down. When the main thread detects event, and the state is #:accepted, it means, that work thread accepted the previous job, and executing it now, so the main thread pulls the state up to need-to-sleep, and the work thread re-executes command (sleeps again in the test case), when the previous external command run has finished. This is intended behaviour. I expect the program to print some garbage, showing that work thread is restarted periodically. Something like that (it is result of using (sleep 1) instead of (system* "sleep" "1s")): $ guile test.scm M: (sleep 3) M: protocol exchange M: new sleep thread M: (sleep 3) R: Going to (sleep 1) R: sleep-loop finished M: protocol exchange M: new sleep thread M: (sleep 3) : (sleep 3)R: Going to (sleep 1) R: sleep-loop finished M: protocol exchange M: new sleep thread M: (sleep 3) R: Going to (sleep 1) R: sleep-loop finished M: protocol exchange M: new sleep thread M: (sleep 3) : (sleep 3)R: Going to (sleep 1) R: sleep-loop finished But what i get with (system* "sleep" "1s") is this: $ guile test.scm M: (sleep 3) M: protocol exchange M: new sleep thread M: (sleep 3) R: Going to (sleep 1) R: sleep-loop finished M: protocol exchange M: (sleep 3) M: protocol exchange M: (sleep 3) M: protocol exchange M: (sleep 3) So, the state of the atomic-box is stuck in #:need-to-sleep somehow. - MB. Respectfully