1 /* |
1 /* |
2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
64 |
64 |
65 // kevent array size |
65 // kevent array size |
66 static final int NUM_KEVENTS = 128; |
66 static final int NUM_KEVENTS = 128; |
67 |
67 |
68 // Are we in a 64-bit VM? |
68 // Are we in a 64-bit VM? |
69 static boolean is64bit = false; |
69 static boolean is64bit; |
70 |
70 |
71 // The kevent array (used for outcoming events only) |
71 // The kevent array (used for outcoming events only) |
72 private AllocatedNativeObject keventArray = null; |
72 private final AllocatedNativeObject keventArray; |
73 private long keventArrayAddress; |
73 private final long keventArrayAddress; |
74 |
74 |
75 // The kqueue fd |
75 // The kqueue fd |
76 private int kq = -1; |
76 private final int kq; |
77 |
77 |
78 // The fd of the interrupt line going out |
78 // The fd of the interrupt line going out |
79 private int outgoingInterruptFD; |
79 private final int outgoingInterruptFD; |
80 |
80 |
81 // The fd of the interrupt line coming in |
|
82 private int incomingInterruptFD; |
|
83 |
81 |
84 static { |
82 static { |
85 IOUtil.load(); |
83 IOUtil.load(); |
86 initStructSizes(); |
84 initStructSizes(); |
87 String datamodel = |
85 String datamodel = |
88 GetPropertyAction.privilegedGetProperty("sun.arch.data.model"); |
86 GetPropertyAction.privilegedGetProperty("sun.arch.data.model"); |
89 is64bit = "64".equals(datamodel); |
87 is64bit = "64".equals(datamodel); |
90 } |
88 } |
91 |
89 |
92 KQueueArrayWrapper() { |
90 KQueueArrayWrapper(int fd0, int fd1) throws IOException { |
93 int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS; |
91 int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS; |
94 keventArray = new AllocatedNativeObject(allocationSize, true); |
92 keventArray = new AllocatedNativeObject(allocationSize, true); |
95 keventArrayAddress = keventArray.address(); |
93 keventArrayAddress = keventArray.address(); |
96 kq = init(); |
94 kq = init(); |
|
95 register0(kq, fd0, 1, 0); |
|
96 outgoingInterruptFD = fd1; |
97 } |
97 } |
98 |
98 |
99 // Used to update file description registrations |
99 // Used to update file description registrations |
100 private static class Update { |
100 private static class Update { |
101 SelChImpl channel; |
101 SelChImpl channel; |
105 this.events = events; |
105 this.events = events; |
106 } |
106 } |
107 } |
107 } |
108 |
108 |
109 private LinkedList<Update> updateList = new LinkedList<Update>(); |
109 private LinkedList<Update> updateList = new LinkedList<Update>(); |
110 |
|
111 void initInterrupt(int fd0, int fd1) { |
|
112 outgoingInterruptFD = fd1; |
|
113 incomingInterruptFD = fd0; |
|
114 register0(kq, fd0, 1, 0); |
|
115 } |
|
116 |
110 |
117 int getReventOps(int index) { |
111 int getReventOps(int index) { |
118 int result = 0; |
112 int result = 0; |
119 int offset = SIZEOF_KEVENT*index + FILTER_OFFSET; |
113 int offset = SIZEOF_KEVENT*index + FILTER_OFFSET; |
120 short filter = keventArray.getShort(offset); |
114 short filter = keventArray.getShort(offset); |
135 int offset = SIZEOF_KEVENT*index + FD_OFFSET; |
129 int offset = SIZEOF_KEVENT*index + FD_OFFSET; |
136 /* The ident field is 8 bytes in 64-bit world, however the API wants us |
130 /* The ident field is 8 bytes in 64-bit world, however the API wants us |
137 * to return an int. Hence read the 8 bytes but return as an int. |
131 * to return an int. Hence read the 8 bytes but return as an int. |
138 */ |
132 */ |
139 if (is64bit) { |
133 if (is64bit) { |
140 long fd = keventArray.getLong(offset); |
134 long fd = keventArray.getLong(offset); |
141 assert fd <= Integer.MAX_VALUE; |
135 assert fd <= Integer.MAX_VALUE; |
142 return (int) fd; |
136 return (int) fd; |
143 } else { |
137 } else { |
144 return keventArray.getInt(offset); |
138 return keventArray.getInt(offset); |
145 } |
139 } |
146 } |
140 } |
147 |
141 |
148 void setInterest(SelChImpl channel, int events) { |
142 void setInterest(SelChImpl channel, int events) { |
149 synchronized (updateList) { |
143 synchronized (updateList) { |
166 } |
160 } |
167 } |
161 } |
168 |
162 |
169 void updateRegistrations() { |
163 void updateRegistrations() { |
170 synchronized (updateList) { |
164 synchronized (updateList) { |
171 Update u = null; |
165 Update u; |
172 while ((u = updateList.poll()) != null) { |
166 while ((u = updateList.poll()) != null) { |
173 SelChImpl ch = u.channel; |
167 SelChImpl ch = u.channel; |
174 if (!ch.isOpen()) |
168 if (!ch.isOpen()) |
175 continue; |
169 continue; |
176 |
170 |
177 register0(kq, ch.getFDVal(), u.events & Net.POLLIN, u.events & Net.POLLOUT); |
171 register0(kq, ch.getFDVal(), u.events & Net.POLLIN, u.events & Net.POLLOUT); |
178 } |
172 } |
179 } |
173 } |
180 } |
174 } |
181 |
175 |
182 |
|
183 void close() throws IOException { |
176 void close() throws IOException { |
184 if (keventArray != null) { |
177 FileDispatcherImpl.closeIntFD(kq); |
185 keventArray.free(); |
178 keventArray.free(); |
186 keventArray = null; |
|
187 } |
|
188 if (kq >= 0) { |
|
189 FileDispatcherImpl.closeIntFD(kq); |
|
190 kq = -1; |
|
191 } |
|
192 } |
179 } |
193 |
180 |
194 int poll(long timeout) { |
181 int poll(long timeout) { |
195 updateRegistrations(); |
182 updateRegistrations(); |
196 int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); |
183 return kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); |
197 return updated; |
|
198 } |
184 } |
199 |
185 |
200 void interrupt() { |
186 void interrupt() { |
201 interrupt(outgoingInterruptFD); |
187 interrupt(outgoingInterruptFD); |
202 } |
188 } |