110 // object to synchronize fd registration changes
111 private final Object updateLock = new Object();
112
113 // number of file descriptors with registration changes pending
114 private int updateCount;
115
116 // file descriptors with registration changes pending
117 private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
118
119 // events for file descriptors with registration changes pending, indexed
120 // by file descriptor and stored as bytes for efficiency reasons. For
121 // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
122 // least then the update is stored in a map.
123 private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
124 private Map<Integer,Byte> eventsHigh;
125
126 // Used by release and updateRegistrations to track whether a file
127 // descriptor is registered with /dev/poll.
128 private final BitSet registered = new BitSet();
129
130 DevPollArrayWrapper() {
131 int allocationSize = NUM_POLLFDS * SIZE_POLLFD;
132 pollArray = new AllocatedNativeObject(allocationSize, true);
133 pollArrayAddress = pollArray.address();
134 wfd = init();
135 if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE)
136 eventsHigh = new HashMap<>();
137 }
138
139 void initInterrupt(int fd0, int fd1) {
140 outgoingInterruptFD = fd1;
141 incomingInterruptFD = fd0;
142 register(wfd, fd0, POLLIN);
143 }
144
145 void putReventOps(int i, int revent) {
146 int offset = SIZE_POLLFD * i + REVENT_OFFSET;
147 pollArray.putShort(offset, (short)revent);
148 }
149
150 int getEventOps(int i) {
151 int offset = SIZE_POLLFD * i + EVENT_OFFSET;
152 return pollArray.getShort(offset);
153 }
154
155 int getReventOps(int i) {
156 int offset = SIZE_POLLFD * i + REVENT_OFFSET;
157 return pollArray.getShort(offset);
158 }
159
183 void setInterest(int fd, int mask) {
184 synchronized (updateLock) {
185 // record the file descriptor and events, expanding the
186 // respective arrays first if necessary.
187 int oldCapacity = updateDescriptors.length;
188 if (updateCount == oldCapacity) {
189 int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
190 int[] newDescriptors = new int[newCapacity];
191 System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
192 updateDescriptors = newDescriptors;
193 }
194 updateDescriptors[updateCount++] = fd;
195
196 // events are stored as bytes for efficiency reasons
197 byte b = (byte)mask;
198 assert (b == mask) && (b != IGNORE);
199 setUpdateEvents(fd, b);
200 }
201 }
202
203 void release(int fd) {
204 synchronized (updateLock) {
205 // ignore any pending update for this file descriptor
206 setUpdateEvents(fd, IGNORE);
207
208 // remove from /dev/poll
209 if (registered.get(fd)) {
210 register(wfd, fd, POLLREMOVE);
211 registered.clear(fd);
212 }
213 }
214 }
215
216 void close() throws IOException {
217 FileDispatcherImpl.closeIntFD(wfd);
218 pollArray.free();
219 }
220
221 int poll(long timeout) throws IOException {
222 updateRegistrations();
223 updated = poll0(pollArrayAddress, NUM_POLLFDS, timeout, wfd);
280 // write any remaining updates
281 if (index > 0)
282 registerMultiple(wfd, pollArray.address(), index);
283
284 updateCount = 0;
285 }
286 }
287
288 private void putPollFD(AllocatedNativeObject array, int index, int fd,
289 short event)
290 {
291 int structIndex = SIZE_POLLFD * index;
292 array.putInt(structIndex + FD_OFFSET, fd);
293 array.putShort(structIndex + EVENT_OFFSET, event);
294 array.putShort(structIndex + REVENT_OFFSET, (short)0);
295 }
296
297 boolean interrupted = false;
298
299 public void interrupt() {
300 interrupt(outgoingInterruptFD);
301 }
302
303 public int interruptedIndex() {
304 return interruptedIndex;
305 }
306
307 boolean interrupted() {
308 return interrupted;
309 }
310
311 void clearInterrupted() {
312 interrupted = false;
313 }
314
315 private native int init();
316 private native void register(int wfd, int fd, int mask);
317 private native void registerMultiple(int wfd, long address, int len)
318 throws IOException;
319 private native int poll0(long pollAddress, int numfds, long timeout,
320 int wfd);
321 private static native void interrupt(int fd);
322
323 static {
324 IOUtil.load();
325 }
326 }
|
110 // object to synchronize fd registration changes
111 private final Object updateLock = new Object();
112
113 // number of file descriptors with registration changes pending
114 private int updateCount;
115
116 // file descriptors with registration changes pending
117 private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
118
119 // events for file descriptors with registration changes pending, indexed
120 // by file descriptor and stored as bytes for efficiency reasons. For
121 // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
122 // least then the update is stored in a map.
123 private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
124 private Map<Integer,Byte> eventsHigh;
125
126 // Used by release and updateRegistrations to track whether a file
127 // descriptor is registered with /dev/poll.
128 private final BitSet registered = new BitSet();
129
130 DevPollArrayWrapper() throws IOException {
131 int allocationSize = NUM_POLLFDS * SIZE_POLLFD;
132 pollArray = new AllocatedNativeObject(allocationSize, true);
133 pollArrayAddress = pollArray.address();
134 wfd = init();
135 if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE)
136 eventsHigh = new HashMap<>();
137 }
138
139 void initInterrupt(int fd0, int fd1) throws IOException {
140 outgoingInterruptFD = fd1;
141 incomingInterruptFD = fd0;
142 register(wfd, fd0, POLLIN);
143 }
144
145 void putReventOps(int i, int revent) {
146 int offset = SIZE_POLLFD * i + REVENT_OFFSET;
147 pollArray.putShort(offset, (short)revent);
148 }
149
150 int getEventOps(int i) {
151 int offset = SIZE_POLLFD * i + EVENT_OFFSET;
152 return pollArray.getShort(offset);
153 }
154
155 int getReventOps(int i) {
156 int offset = SIZE_POLLFD * i + REVENT_OFFSET;
157 return pollArray.getShort(offset);
158 }
159
183 void setInterest(int fd, int mask) {
184 synchronized (updateLock) {
185 // record the file descriptor and events, expanding the
186 // respective arrays first if necessary.
187 int oldCapacity = updateDescriptors.length;
188 if (updateCount == oldCapacity) {
189 int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
190 int[] newDescriptors = new int[newCapacity];
191 System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
192 updateDescriptors = newDescriptors;
193 }
194 updateDescriptors[updateCount++] = fd;
195
196 // events are stored as bytes for efficiency reasons
197 byte b = (byte)mask;
198 assert (b == mask) && (b != IGNORE);
199 setUpdateEvents(fd, b);
200 }
201 }
202
203 void release(int fd) throws IOException {
204 synchronized (updateLock) {
205 // ignore any pending update for this file descriptor
206 setUpdateEvents(fd, IGNORE);
207
208 // remove from /dev/poll
209 if (registered.get(fd)) {
210 register(wfd, fd, POLLREMOVE);
211 registered.clear(fd);
212 }
213 }
214 }
215
216 void close() throws IOException {
217 FileDispatcherImpl.closeIntFD(wfd);
218 pollArray.free();
219 }
220
221 int poll(long timeout) throws IOException {
222 updateRegistrations();
223 updated = poll0(pollArrayAddress, NUM_POLLFDS, timeout, wfd);
280 // write any remaining updates
281 if (index > 0)
282 registerMultiple(wfd, pollArray.address(), index);
283
284 updateCount = 0;
285 }
286 }
287
288 private void putPollFD(AllocatedNativeObject array, int index, int fd,
289 short event)
290 {
291 int structIndex = SIZE_POLLFD * index;
292 array.putInt(structIndex + FD_OFFSET, fd);
293 array.putShort(structIndex + EVENT_OFFSET, event);
294 array.putShort(structIndex + REVENT_OFFSET, (short)0);
295 }
296
297 boolean interrupted = false;
298
299 public void interrupt() {
300 try {
301 IOUtil.write1(outgoingInterruptFD, (byte)0);
302 } catch (IOException ioe) {
303 throw new InternalError(ioe);
304 }
305 }
306
307 public int interruptedIndex() {
308 return interruptedIndex;
309 }
310
311 boolean interrupted() {
312 return interrupted;
313 }
314
315 void clearInterrupted() {
316 interrupted = false;
317 }
318
319 private native int init() throws IOException;
320 private native void register(int wfd, int fd, int mask) throws IOException;
321 private native void registerMultiple(int wfd, long address, int len)
322 throws IOException;
323 private native int poll0(long pollAddress, int numfds, long timeout, int wfd)
324 throws IOException;
325
326 static {
327 IOUtil.load();
328 }
329 }
|