annotate agent/src/os/win32/serverLists.cpp @ 1552:c18cbe5936b8

6941466: Oracle rebranding changes for Hotspot repositories Summary: Change all the Sun copyrights to Oracle copyright Reviewed-by: ohair
author trims
date Thu, 27 May 2010 19:08:38 -0700
parents a61af66fc99e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include <assert.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "serverLists.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Lists
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 CRITICAL_SECTION Lists::crit;
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 void
a61af66fc99e Initial load
duke
parents:
diff changeset
35 Lists::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
36 InitializeCriticalSection(&crit);
a61af66fc99e Initial load
duke
parents:
diff changeset
37 }
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 void
a61af66fc99e Initial load
duke
parents:
diff changeset
40 Lists::lock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 EnterCriticalSection(&crit);
a61af66fc99e Initial load
duke
parents:
diff changeset
42 }
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 void
a61af66fc99e Initial load
duke
parents:
diff changeset
45 Lists::unlock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 LeaveCriticalSection(&crit);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // ListsLocker
a61af66fc99e Initial load
duke
parents:
diff changeset
51 //
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 ListsLocker::ListsLocker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 Lists::lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
55 }
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 ListsLocker::~ListsLocker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 Lists::unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // ChildInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
63 //
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 ChildInfo::ChildInfo(DWORD pid, HANDLE childProcessHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 HANDLE writeToStdinHandle, HANDLE readFromStdoutHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
67 HANDLE auxHandle1, HANDLE auxHandle2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 this->pid = pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 this->childProcessHandle = childProcessHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 this->writeToStdinHandle = writeToStdinHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 this->readFromStdoutHandle = readFromStdoutHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 this->auxHandle1 = auxHandle1;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 this->auxHandle2 = auxHandle2;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 client = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 DWORD
a61af66fc99e Initial load
duke
parents:
diff changeset
78 ChildInfo::getPid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 HANDLE
a61af66fc99e Initial load
duke
parents:
diff changeset
83 ChildInfo::getChildProcessHandle() {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return childProcessHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 HANDLE
a61af66fc99e Initial load
duke
parents:
diff changeset
88 ChildInfo::getWriteToStdinHandle() {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return writeToStdinHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 HANDLE
a61af66fc99e Initial load
duke
parents:
diff changeset
93 ChildInfo::getReadFromStdoutHandle() {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 return readFromStdoutHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void
a61af66fc99e Initial load
duke
parents:
diff changeset
98 ChildInfo::setClient(ClientInfo* clientInfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 client = clientInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 ClientInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
103 ChildInfo::getClient() {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 return client;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void
a61af66fc99e Initial load
duke
parents:
diff changeset
108 ChildInfo::closeAll() {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 CloseHandle(childProcessHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 CloseHandle(writeToStdinHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 CloseHandle(readFromStdoutHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 CloseHandle(auxHandle1);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 CloseHandle(auxHandle2);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // ChildList
a61af66fc99e Initial load
duke
parents:
diff changeset
118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 ChildList::ChildList() {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 ChildList::~ChildList() {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 void
a61af66fc99e Initial load
duke
parents:
diff changeset
127 ChildList::addChild(ChildInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Could store these in binary sorted order by pid for efficiency
a61af66fc99e Initial load
duke
parents:
diff changeset
129 childList.push_back(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 ChildInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
133 ChildList::removeChild(HANDLE childProcessHandle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 ChildInfo* info = *iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (info->getChildProcessHandle() == childProcessHandle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 childList.erase(iter);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return info;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 assert(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 void
a61af66fc99e Initial load
duke
parents:
diff changeset
147 ChildList::removeChild(ChildInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
149 iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (*iter == info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 childList.erase(iter);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 assert(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 ChildInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
159 ChildList::getChildByPid(DWORD pid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
161 iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 ChildInfo* info = *iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (info->getPid() == pid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 return info;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 int
a61af66fc99e Initial load
duke
parents:
diff changeset
171 ChildList::size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return childList.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 ChildInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
176 ChildList::getChildByIndex(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return childList[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // ClientInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
182 //
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 ClientInfo::ClientInfo(SOCKET dataSocket) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 this->dataSocket = dataSocket;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 buf = new IOBuf(32768, 131072);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 buf->setSocket(dataSocket);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 ClientInfo::~ClientInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 delete buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 SOCKET
a61af66fc99e Initial load
duke
parents:
diff changeset
196 ClientInfo::getDataSocket() {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return dataSocket;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 IOBuf*
a61af66fc99e Initial load
duke
parents:
diff changeset
201 ClientInfo::getIOBuf() {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 void
a61af66fc99e Initial load
duke
parents:
diff changeset
206 ClientInfo::setTarget(ChildInfo* childInfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 target = childInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 ChildInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
211 ClientInfo::getTarget() {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 return target;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 void
a61af66fc99e Initial load
duke
parents:
diff changeset
216 ClientInfo::closeAll() {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 shutdown(dataSocket, SD_BOTH);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 closesocket(dataSocket);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 dataSocket = INVALID_SOCKET;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // ClientList
a61af66fc99e Initial load
duke
parents:
diff changeset
224 //
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 ClientList::ClientList() {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 ClientList::~ClientList() {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 void
a61af66fc99e Initial load
duke
parents:
diff changeset
233 ClientList::addClient(ClientInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 clientList.push_back(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
238 ClientList::isAnyDataSocketSet(fd_set* fds, ClientInfo** out) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
240 iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 ClientInfo* info = *iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (FD_ISSET(info->getDataSocket(), fds)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 *out = info;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 void
a61af66fc99e Initial load
duke
parents:
diff changeset
251 ClientList::removeClient(ClientInfo* client) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (*iter == client) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 clientList.erase(iter);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 assert(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 int
a61af66fc99e Initial load
duke
parents:
diff changeset
263 ClientList::size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 return clientList.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 ClientInfo*
a61af66fc99e Initial load
duke
parents:
diff changeset
268 ClientList::get(int num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 return clientList[num];
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }