src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java
changeset 58439 b25362cec8ce
parent 47216 71c04702a3d5
equal deleted inserted replaced
58438:1181f58f30e2 58439:b25362cec8ce
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2019, 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
    24  */
    24  */
    25 
    25 
    26 package java.nio.channels.spi;
    26 package java.nio.channels.spi;
    27 
    27 
    28 import java.io.IOException;
    28 import java.io.IOException;
       
    29 import java.lang.invoke.MethodHandles;
       
    30 import java.lang.invoke.VarHandle;
    29 import java.nio.channels.SelectionKey;
    31 import java.nio.channels.SelectionKey;
    30 import java.nio.channels.Selector;
    32 import java.nio.channels.Selector;
    31 import java.util.HashSet;
    33 import java.util.HashSet;
    32 import java.util.Set;
    34 import java.util.Set;
    33 import sun.nio.ch.Interruptible;
    35 import sun.nio.ch.Interruptible;
    34 import java.util.concurrent.atomic.AtomicBoolean;
    36 import sun.nio.ch.SelectorImpl;
    35 
    37 
    36 
    38 
    37 /**
    39 /**
    38  * Base implementation class for selectors.
    40  * Base implementation class for selectors.
    39  *
    41  *
    67  */
    69  */
    68 
    70 
    69 public abstract class AbstractSelector
    71 public abstract class AbstractSelector
    70     extends Selector
    72     extends Selector
    71 {
    73 {
    72 
    74     private static final VarHandle CLOSED;
    73     private final AtomicBoolean selectorOpen = new AtomicBoolean(true);
    75     static {
       
    76         try {
       
    77             MethodHandles.Lookup l = MethodHandles.lookup();
       
    78             CLOSED = l.findVarHandle(AbstractSelector.class, "closed", boolean.class);
       
    79         } catch (Exception e) {
       
    80             throw new InternalError(e);
       
    81         }
       
    82     }
       
    83     private volatile boolean closed;
    74 
    84 
    75     // The provider that created this selector
    85     // The provider that created this selector
    76     private final SelectorProvider provider;
    86     private final SelectorProvider provider;
    77 
    87 
       
    88     // cancelled-key, not used by the JDK Selector implementations
       
    89     private final Set<SelectionKey> cancelledKeys;
       
    90 
    78     /**
    91     /**
    79      * Initializes a new instance of this class.
    92      * Initializes a new instance of this class.
    80      *
    93      *
    81      * @param  provider
    94      * @param  provider
    82      *         The provider that created this selector
    95      *         The provider that created this selector
    83      */
    96      */
    84     protected AbstractSelector(SelectorProvider provider) {
    97     protected AbstractSelector(SelectorProvider provider) {
    85         this.provider = provider;
    98         this.provider = provider;
    86     }
    99         if (this instanceof SelectorImpl) {
    87 
   100             // not used in JDK Selector implementations
    88     private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
   101             this.cancelledKeys = Set.of();
       
   102         } else {
       
   103             this.cancelledKeys = new HashSet<>();
       
   104         }
       
   105     }
    89 
   106 
    90     void cancel(SelectionKey k) {                       // package-private
   107     void cancel(SelectionKey k) {                       // package-private
    91         synchronized (cancelledKeys) {
   108         synchronized (cancelledKeys) {
    92             cancelledKeys.add(k);
   109             cancelledKeys.add(k);
    93         }
   110         }
   103      *
   120      *
   104      * @throws  IOException
   121      * @throws  IOException
   105      *          If an I/O error occurs
   122      *          If an I/O error occurs
   106      */
   123      */
   107     public final void close() throws IOException {
   124     public final void close() throws IOException {
   108         boolean open = selectorOpen.getAndSet(false);
   125         boolean changed = (boolean) CLOSED.compareAndSet(this, false, true);
   109         if (!open)
   126         if (changed) {
   110             return;
   127             implCloseSelector();
   111         implCloseSelector();
   128         }
   112     }
   129     }
   113 
   130 
   114     /**
   131     /**
   115      * Closes this selector.
   132      * Closes this selector.
   116      *
   133      *
   128      *          If an I/O error occurs while closing the selector
   145      *          If an I/O error occurs while closing the selector
   129      */
   146      */
   130     protected abstract void implCloseSelector() throws IOException;
   147     protected abstract void implCloseSelector() throws IOException;
   131 
   148 
   132     public final boolean isOpen() {
   149     public final boolean isOpen() {
   133         return selectorOpen.get();
   150         return !closed;
   134     }
   151     }
   135 
   152 
   136     /**
   153     /**
   137      * Returns the provider that created this channel.
   154      * Returns the provider that created this channel.
   138      *
   155      *