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+
26+package sun.nio.fs;
27+
28+import java.nio.file.*;
29+import java.security.AccessController;
30+import java.security.PrivilegedAction;
31+import java.io.IOException;
32+import 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+
41+abstract 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