History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/nio/fs/AbstractPoller.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/nio/fs/AbstractPoller.java+290−0
@@ -0,0 +1,290 @@
1/*
2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.nio.fs;
27
28import java.nio.file.*;
29import java.security.AccessController;
30import java.security.PrivilegedAction;
31import java.io.IOException;
32import java.util.*;
33
34/**
35 * Base implementation of background poller thread used in watch service
36 * implementations. A poller thread waits on events from the file system and
37 * also services "requests" from clients to register for new events or cancel
38 * existing registrations.
39 */
40
41abstract class AbstractPoller implements Runnable {
42
43 // list of requests pending to the poller thread
44 private final LinkedList<Request> requestList;
45
46 // set to true when shutdown
47 private boolean shutdown;
48
49 protected AbstractPoller() {
50 this.requestList = new LinkedList<Request>();
51 this.shutdown = false;
52 }
53
54 /**
55 * Starts the poller thread
56 */
57 public void start() {
58 final Runnable thisRunnable = this;
59 AccessController.doPrivileged(new PrivilegedAction<Object>() {
60 @Override
61 public Object run() {
62 Thread thr = new Thread(thisRunnable);
63 thr.setDaemon(true);
64 thr.start();
65 return null;
66 }
67 });
68 }
69
70 /**
71 * Wakeup poller thread so that it can service pending requests
72 */
73 abstract void wakeup() throws IOException;
74
75 /**
76 * Executed by poller thread to register directory for changes
77 */
78 abstract Object implRegister(Path path,
79 Set<? extends WatchEvent.Kind<?>> events,
80 WatchEvent.Modifier... modifiers);
81
82 /**
83 * Executed by poller thread to cancel key
84 */
85 abstract void implCancelKey(WatchKey key);
86
87 /**
88 * Executed by poller thread to shutdown and cancel all keys
89 */
90 abstract void implCloseAll();
91
92 /**
93 * Requests, and waits on, poller thread to register given file.
94 */
95 final WatchKey register(Path dir,
96 WatchEvent.Kind<?>[] events,
97 WatchEvent.Modifier... modifiers)
98 throws IOException
99 {
100 // validate arguments before request to poller
101 if (dir == null)
102 throw new NullPointerException();
103 if (events.length == 0)
104 throw new IllegalArgumentException("No events to register");
105 Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
106 for (WatchEvent.Kind<?> event: events) {
107 // standard events
108 if (event == StandardWatchEventKinds.ENTRY_CREATE ||
109 event == StandardWatchEventKinds.ENTRY_MODIFY ||
110 event == StandardWatchEventKinds.ENTRY_DELETE)
111 {
112 eventSet.add(event);
113 continue;
114 }
115
116 // OVERFLOW is ignored
117 if (event == StandardWatchEventKinds.OVERFLOW) {
118 if (events.length == 1)
119 throw new IllegalArgumentException("No events to register");
120 continue;
121 }
122
123 // null/unsupported
124 if (event == null)
125 throw new NullPointerException("An element in event set is 'null'");
126 throw new UnsupportedOperationException(event.name());
127 }
128 return (WatchKey)invoke(RequestType.REGISTER, dir, eventSet, modifiers);
129 }
130
131 /**
132 * Cancels, and waits on, poller thread to cancel given key.
133 */
134 final void cancel(WatchKey key) {
135 try {
136 invoke(RequestType.CANCEL, key);
137 } catch (IOException x) {
138 // should not happen
139 throw new AssertionError(x.getMessage());
140 }
141 }
142
143 /**
144 * Shutdown poller thread
145 */
146 final void close() throws IOException {
147 invoke(RequestType.CLOSE);
148 }
149
150 /**
151 * Types of request that the poller thread must handle
152 */
153 private static enum RequestType {
154 REGISTER,
155 CANCEL,
156 CLOSE;
157 }
158
159 /**
160 * Encapsulates a request (command) to the poller thread.
161 */
162 private static class Request {
163 private final RequestType type;
164 private final Object[] params;
165
166 private boolean completed = false;
167 private Object result = null;
168
169 Request(RequestType type, Object... params) {
170 this.type = type;
171 this.params = params;
172 }
173
174 RequestType type() {
175 return type;
176 }
177
178 Object[] parameters() {
179 return params;
180 }
181
182 void release(Object result) {
183 synchronized (this) {
184 this.completed = true;
185 this.result = result;
186 notifyAll();
187 }
188 }
189
190 /**
191 * Await completion of the request. The return value is the result of
192 * the request.
193 */
194 Object awaitResult() {
195 synchronized (this) {
196 while (!completed) {
197 try {
198 wait();
199 } catch (InterruptedException x) {
200 // ignore
201 }
202 }
203 return result;
204 }
205 }
206 }
207
208 /**
209 * Enqueues request to poller thread and waits for result
210 */
211 private Object invoke(RequestType type, Object... params) throws IOException {
212 // submit request
213 Request req = new Request(type, params);
214 synchronized (requestList) {
215 if (shutdown) {
216 throw new ClosedWatchServiceException();
217 }
218 requestList.add(req);
219 }
220
221 // wakeup thread
222 wakeup();
223
224 // wait for result
225 Object result = req.awaitResult();
226
227 if (result instanceof RuntimeException)
228 throw (RuntimeException)result;
229 if (result instanceof IOException )
230 throw (IOException)result;
231 return result;
232 }
233
234 /**
235 * Invoked by poller thread to process all pending requests
236 *
237 * @return true if poller thread should shutdown
238 */
239 @SuppressWarnings("unchecked")
240 boolean processRequests() {
241 synchronized (requestList) {
242 Request req;
243 while ((req = requestList.poll()) != null) {
244 // if in process of shutdown then reject request
245 if (shutdown) {
246 req.release(new ClosedWatchServiceException());
247 }
248
249 switch (req.type()) {
250 /**
251 * Register directory
252 */
253 case REGISTER: {
254 Object[] params = req.parameters();
255 Path path = (Path)params[0];
256 Set<? extends WatchEvent.Kind<?>> events =
257 (Set<? extends WatchEvent.Kind<?>>)params[1];
258 WatchEvent.Modifier[] modifiers =
259 (WatchEvent.Modifier[])params[2];
260 req.release(implRegister(path, events, modifiers));
261 break;
262 }
263 /**
264 * Cancel existing key
265 */
266 case CANCEL : {
267 Object[] params = req.parameters();
268 WatchKey key = (WatchKey)params[0];
269 implCancelKey(key);
270 req.release(null);
271 break;
272 }
273 /**
274 * Close watch service
275 */
276 case CLOSE: {
277 implCloseAll();
278 req.release(null);
279 shutdown = true;
280 break;
281 }
282
283 default:
284 req.release(new IOException("request not recognized"));
285 }
286 }
287 }
288 return shutdown;
289 }
290}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t