src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
changeset 49248 15a0e60c8b97
parent 47216 71c04702a3d5
equal deleted inserted replaced
49247:95e00d2708fb 49248:15a0e60c8b97
     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     }