1 /*
2 * Copyright (c) 2012, 2013, 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
167
168 // invoked by clients to register a file descriptor
169 @Override
170 void startPoll(int fd, int events) {
171 // We use a separate filter for read and write events.
172 // TBD: Measure cost of EV_ONESHOT vs. EV_CLEAR, either will do here.
173 int err = 0;
174 int flags = (EV_ADD|EV_ONESHOT);
175 if ((events & Net.POLLIN) > 0)
176 err = keventRegister(kqfd, fd, EVFILT_READ, flags);
177 if (err == 0 && (events & Net.POLLOUT) > 0)
178 err = keventRegister(kqfd, fd, EVFILT_WRITE, flags);
179 if (err != 0)
180 throw new InternalError("kevent failed: " + err); // should not happen
181 }
182
183 /*
184 * Task to process events from kqueue and dispatch to the channel's
185 * onEvent handler.
186 *
187 * Events are retreived from kqueue in batch and offered to a BlockingQueue
188 * where they are consumed by handler threads. A special "NEED_TO_POLL"
189 * event is used to signal one consumer to re-poll when all events have
190 * been consumed.
191 */
192 private class EventHandlerTask implements Runnable {
193 private Event poll() throws IOException {
194 try {
195 for (;;) {
196 int n = keventPoll(kqfd, address, MAX_KEVENTS_TO_POLL);
197 /*
198 * 'n' events have been read. Here we map them to their
199 * corresponding channel in batch and queue n-1 so that
200 * they can be handled by other handler threads. The last
201 * event is handled by this thread (and so is not queued).
202 */
203 fdToChannelLock.readLock().lock();
204 try {
205 while (n-- > 0) {
206 long keventAddress = getEvent(address, n);
207 int fd = getDescriptor(keventAddress);
|
1 /*
2 * Copyright (c) 2012, 2018, 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
167
168 // invoked by clients to register a file descriptor
169 @Override
170 void startPoll(int fd, int events) {
171 // We use a separate filter for read and write events.
172 // TBD: Measure cost of EV_ONESHOT vs. EV_CLEAR, either will do here.
173 int err = 0;
174 int flags = (EV_ADD|EV_ONESHOT);
175 if ((events & Net.POLLIN) > 0)
176 err = keventRegister(kqfd, fd, EVFILT_READ, flags);
177 if (err == 0 && (events & Net.POLLOUT) > 0)
178 err = keventRegister(kqfd, fd, EVFILT_WRITE, flags);
179 if (err != 0)
180 throw new InternalError("kevent failed: " + err); // should not happen
181 }
182
183 /*
184 * Task to process events from kqueue and dispatch to the channel's
185 * onEvent handler.
186 *
187 * Events are retrieved from kqueue in batch and offered to a BlockingQueue
188 * where they are consumed by handler threads. A special "NEED_TO_POLL"
189 * event is used to signal one consumer to re-poll when all events have
190 * been consumed.
191 */
192 private class EventHandlerTask implements Runnable {
193 private Event poll() throws IOException {
194 try {
195 for (;;) {
196 int n = keventPoll(kqfd, address, MAX_KEVENTS_TO_POLL);
197 /*
198 * 'n' events have been read. Here we map them to their
199 * corresponding channel in batch and queue n-1 so that
200 * they can be handled by other handler threads. The last
201 * event is handled by this thread (and so is not queued).
202 */
203 fdToChannelLock.readLock().lock();
204 try {
205 while (n-- > 0) {
206 long keventAddress = getEvent(address, n);
207 int fd = getDescriptor(keventAddress);
|