| 2522 | } |
| 2523 | |
| 2524 | static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) |
| 2525 | { |
| 2526 | int i; |
| 2527 | |
| 2528 | /* If data were just reported data, release the pipe's thread. */ |
| 2529 | if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { |
| 2530 | KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); |
| 2531 | ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); |
| 2532 | cp->CurrentIndex = KWSYSPE_PIPE_COUNT; |
| 2533 | } |
| 2534 | |
| 2535 | /* Wakeup all reading threads that are not on closed pipes. */ |
| 2536 | for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { |
| 2537 | /* The wakeup threads will write one byte to the pipe write ends. |
| 2538 | If there are no data in the pipe then this is enough to wakeup |
| 2539 | the reading threads. If there are already data in the pipe |
| 2540 | this may block. We cannot use PeekNamedPipe to check whether |
| 2541 | there are data because an outside process might still be |
| 2542 | writing data if we are disowning it. Also, PeekNamedPipe will |
| 2543 | block if checking a pipe on which the reading thread is |
| 2544 | currently calling ReadPipe. Therefore we need a separate |
| 2545 | thread to call WriteFile. If it blocks, that is okay because |
| 2546 | it will unblock when we close the read end and break the pipe |
| 2547 | below. */ |
| 2548 | if (cp->Pipe[i].Read) { |
| 2549 | KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i)); |
| 2550 | ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0); |
| 2551 | } |
| 2552 | } |
| 2553 | |
| 2554 | /* Tell pipe threads to reset until we run another process. */ |
| 2555 | while (cp->PipesLeft > 0) { |
| 2556 | /* The waking threads will cause all reading threads to report. |
| 2557 | Wait for the next one and save its index. */ |
| 2558 | KWSYSPE_DEBUG((stderr, "waiting for reader\n")); |
| 2559 | WaitForSingleObject(cp->Full, INFINITE); |
| 2560 | cp->CurrentIndex = cp->SharedIndex; |
| 2561 | ReleaseSemaphore(cp->SharedIndexMutex, 1, 0); |
| 2562 | KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex)); |
| 2563 | |
| 2564 | /* We are done reading this pipe. Close its read handle. */ |
| 2565 | cp->Pipe[cp->CurrentIndex].Closed = 1; |
| 2566 | kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read); |
| 2567 | --cp->PipesLeft; |
| 2568 | |
| 2569 | /* Tell the reading thread we are done with the data. It will |
| 2570 | reset immediately because the pipe is closed. */ |
| 2571 | ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); |
| 2572 | } |
| 2573 | } |
| 2574 | |
| 2575 | /* Global set of executing processes for use by the Ctrl handler. |
| 2576 | This global instance will be zero-initialized by the compiler. |
no test coverage detected
searching dependent graphs…