src/java.base/share/classes/java/nio/channels/spi/AbstractSelectionKey.java
changeset 58439 b25362cec8ce
parent 47216 71c04702a3d5
equal deleted inserted replaced
58438:1181f58f30e2 58439:b25362cec8ce
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2013, 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
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.nio.channels.spi;
    26 package java.nio.channels.spi;
    27 
    27 
    28 import java.nio.channels.*;
    28 import java.lang.invoke.MethodHandles;
       
    29 import java.lang.invoke.VarHandle;
       
    30 import java.nio.channels.SelectionKey;
       
    31 import java.nio.channels.Selector;
    29 
    32 
       
    33 import sun.nio.ch.SelectionKeyImpl;
       
    34 import sun.nio.ch.SelectorImpl;
    30 
    35 
    31 /**
    36 /**
    32  * Base implementation class for selection keys.
    37  * Base implementation class for selection keys.
    33  *
    38  *
    34  * <p> This class tracks the validity of the key and implements cancellation.
    39  * <p> This class tracks the validity of the key and implements cancellation.
    39  */
    44  */
    40 
    45 
    41 public abstract class AbstractSelectionKey
    46 public abstract class AbstractSelectionKey
    42     extends SelectionKey
    47     extends SelectionKey
    43 {
    48 {
       
    49     private static final VarHandle INVALID;
       
    50     static {
       
    51         try {
       
    52             MethodHandles.Lookup l = MethodHandles.lookup();
       
    53             INVALID = l.findVarHandle(AbstractSelectionKey.class, "invalid", boolean.class);
       
    54         } catch (Exception e) {
       
    55             throw new InternalError(e);
       
    56         }
       
    57     }
    44 
    58 
    45     /**
    59     /**
    46      * Initializes a new instance of this class.
    60      * Initializes a new instance of this class.
    47      */
    61      */
    48     protected AbstractSelectionKey() { }
    62     protected AbstractSelectionKey() { }
    49 
    63 
    50     private volatile boolean valid = true;
    64     private volatile boolean invalid;
    51 
    65 
    52     public final boolean isValid() {
    66     public final boolean isValid() {
    53         return valid;
    67         return !invalid;
    54     }
    68     }
    55 
    69 
    56     void invalidate() {                                 // package-private
    70     void invalidate() {                                 // package-private
    57         valid = false;
    71         invalid = true;
    58     }
    72     }
    59 
    73 
    60     /**
    74     /**
    61      * Cancels this key.
    75      * Cancels this key.
    62      *
    76      *
    63      * <p> If this key has not yet been cancelled then it is added to its
    77      * <p> If this key has not yet been cancelled then it is added to its
    64      * selector's cancelled-key set while synchronized on that set.  </p>
    78      * selector's cancelled-key set while synchronized on that set.  </p>
    65      */
    79      */
    66     public final void cancel() {
    80     public final void cancel() {
    67         // Synchronizing "this" to prevent this key from getting canceled
    81         boolean changed = (boolean) INVALID.compareAndSet(this, false, true);
    68         // multiple times by different threads, which might cause race
    82         if (changed) {
    69         // condition between selector's select() and channel's close().
    83             Selector sel = selector();
    70         synchronized (this) {
    84             if (sel instanceof SelectorImpl) {
    71             if (valid) {
    85                 // queue cancelled key directly
    72                 valid = false;
    86                 ((SelectorImpl) sel).cancel((SelectionKeyImpl) this);
    73                 ((AbstractSelector)selector()).cancel(this);
    87             } else {
       
    88                 ((AbstractSelector) sel).cancel(this);
    74             }
    89             }
    75         }
    90         }
    76     }
    91     }
    77 }
    92 }