Mercurial > hg > truffle
annotate agent/src/os/win32/Reaper.cpp @ 2385:0e3ed5a14f73
Merge
author | jcoomes |
---|---|
date | Thu, 24 Mar 2011 23:04:36 -0700 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include <iostream> | |
26 #include "Reaper.hpp" | |
27 | |
28 using namespace std; | |
29 | |
30 Reaper::Reaper(ReaperCB* cb) { | |
31 InitializeCriticalSection(&crit); | |
32 event = CreateEvent(NULL, TRUE, FALSE, NULL); | |
33 this->cb = cb; | |
34 | |
35 active = false; | |
36 shouldShutDown = false; | |
37 } | |
38 | |
39 bool | |
40 Reaper::start() { | |
41 bool result = false; | |
42 | |
43 EnterCriticalSection(&crit); | |
44 | |
45 if (!active) { | |
46 DWORD id; | |
47 HANDLE reaper = CreateThread(NULL, 0, &Reaper::reaperThreadEntry, | |
48 this, 0, &id); | |
49 if (reaper != NULL) { | |
50 result = true; | |
51 } | |
52 } | |
53 | |
54 LeaveCriticalSection(&crit); | |
55 | |
56 return result; | |
57 } | |
58 | |
59 bool | |
60 Reaper::stop() { | |
61 bool result = false; | |
62 | |
63 EnterCriticalSection(&crit); | |
64 | |
65 if (active) { | |
66 shouldShutDown = true; | |
67 SetEvent(event); | |
68 while (active) { | |
69 Sleep(1); | |
70 } | |
71 shouldShutDown = false; | |
72 result = true; | |
73 } | |
74 | |
75 LeaveCriticalSection(&crit); | |
76 | |
77 return result; | |
78 } | |
79 | |
80 void | |
81 Reaper::registerProcess(HANDLE processHandle, void* userData) { | |
82 ProcessInfo info; | |
83 | |
84 info.handle = processHandle; | |
85 info.userData = userData; | |
86 | |
87 EnterCriticalSection(&crit); | |
88 | |
89 procInfo.push_back(info); | |
90 SetEvent(event); | |
91 | |
92 LeaveCriticalSection(&crit); | |
93 } | |
94 | |
95 void | |
96 Reaper::reaperThread() { | |
97 while (!shouldShutDown) { | |
98 // Take atomic snapshot of the current process list and user data | |
99 EnterCriticalSection(&crit); | |
100 | |
101 int num = procInfo.size(); | |
102 HANDLE* handleList = new HANDLE[1 + num]; | |
103 void** dataList = new void*[num]; | |
104 for (int i = 0; i < num; i++) { | |
105 handleList[i] = procInfo[i].handle; | |
106 dataList[i] = procInfo[i].userData; | |
107 } | |
108 | |
109 LeaveCriticalSection(&crit); | |
110 | |
111 // Topmost handle becomes the event object, so other threads can | |
112 // signal this one to notice differences in the above list (or | |
113 // shut down) | |
114 handleList[num] = event; | |
115 | |
116 // Wait for these objects | |
117 DWORD idx = WaitForMultipleObjects(1 + num, handleList, | |
118 FALSE, INFINITE); | |
119 if ((idx >= WAIT_OBJECT_0) && (idx <= WAIT_OBJECT_0 + num)) { | |
120 idx -= WAIT_OBJECT_0; | |
121 if (idx < num) { | |
122 // A process exited (i.e., it wasn't that we were woken up | |
123 // just because the event went off) | |
124 (*cb)(dataList[idx]); | |
125 // Remove this process from the list (NOTE: requires that | |
126 // ordering does not change, i.e., that all additions are to | |
127 // the back of the process list) | |
128 EnterCriticalSection(&crit); | |
129 | |
130 std::vector<ProcessInfo>::iterator iter = procInfo.begin(); | |
131 iter += idx; | |
132 procInfo.erase(iter); | |
133 | |
134 LeaveCriticalSection(&crit); | |
135 } else { | |
136 // Notification from other thread | |
137 ResetEvent(event); | |
138 } | |
139 } else { | |
140 // Unexpected return value. For now, warn. | |
141 cerr << "Reaper::reaperThread(): unexpected return value " | |
142 << idx << " from WaitForMultipleObjects" << endl; | |
143 } | |
144 | |
145 // Clean up these lists | |
146 delete[] handleList; | |
147 delete[] dataList; | |
148 } | |
149 | |
150 // Time to shut down | |
151 active = false; | |
152 } | |
153 | |
154 DWORD WINAPI | |
155 Reaper::reaperThreadEntry(LPVOID data) { | |
156 Reaper* reaper = (Reaper*) data; | |
157 reaper->reaperThread(); | |
158 return 0; | |
159 } |