installed pty
[VSoRC/.git] / node_modules / node-pty / deps / winpty / src / agent / EventLoop.cc
1 // Copyright (c) 2011-2012 Ryan Prichard
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20
21 #include "EventLoop.h"
22
23 #include <algorithm>
24
25 #include "NamedPipe.h"
26 #include "../shared/DebugClient.h"
27 #include "../shared/WinptyAssert.h"
28
29 EventLoop::~EventLoop() {
30     for (NamedPipe *pipe : m_pipes) {
31         delete pipe;
32     }
33     m_pipes.clear();
34 }
35
36 // Enter the event loop.  Runs until the I/O or timeout handler calls exit().
37 void EventLoop::run()
38 {
39     std::vector<HANDLE> waitHandles;
40     DWORD lastTime = GetTickCount();
41     while (!m_exiting) {
42         bool didSomething = false;
43
44         // Attempt to make progress with the pipes.
45         waitHandles.clear();
46         for (size_t i = 0; i < m_pipes.size(); ++i) {
47             if (m_pipes[i]->serviceIo(&waitHandles)) {
48                 onPipeIo(*m_pipes[i]);
49                 didSomething = true;
50             }
51         }
52
53         // Call the timeout if enough time has elapsed.
54         if (m_pollInterval > 0) {
55             int elapsed = GetTickCount() - lastTime;
56             if (elapsed >= m_pollInterval) {
57                 onPollTimeout();
58                 lastTime = GetTickCount();
59                 didSomething = true;
60             }
61         }
62
63         if (didSomething)
64             continue;
65
66         // If there's nothing to do, wait.
67         DWORD timeout = INFINITE;
68         if (m_pollInterval > 0)
69             timeout = std::max(0, (int)(lastTime + m_pollInterval - GetTickCount()));
70         if (waitHandles.size() == 0) {
71             ASSERT(timeout != INFINITE);
72             if (timeout > 0)
73                 Sleep(timeout);
74         } else {
75             DWORD result = WaitForMultipleObjects(waitHandles.size(),
76                                                   waitHandles.data(),
77                                                   FALSE,
78                                                   timeout);
79             ASSERT(result != WAIT_FAILED);
80         }
81     }
82 }
83
84 NamedPipe &EventLoop::createNamedPipe()
85 {
86     NamedPipe *ret = new NamedPipe();
87     m_pipes.push_back(ret);
88     return *ret;
89 }
90
91 void EventLoop::setPollInterval(int ms)
92 {
93     m_pollInterval = ms;
94 }
95
96 void EventLoop::shutdown()
97 {
98     m_exiting = true;
99 }