View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2024 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix;
19  
20  import java.nio.channels.SelectableChannel;
21  import java.nio.channels.SelectionKey;
22  import java.nio.channels.Selector;
23  import java.nio.channels.spi.AbstractSelectableChannel;
24  import java.util.concurrent.atomic.AtomicBoolean;
25  
26  final class AFSelectionKey extends SelectionKey {
27    private static final int OP_INVALID = 1 << 7; // custom
28    private final AFSelector sel;
29    private final AFSocketCore core;
30    private int ops;
31    private final SelectableChannel chann;
32    private final AtomicBoolean cancelled = new AtomicBoolean();
33    private int opsReady;
34  
35    AFSelectionKey(AFSelector selector, AbstractSelectableChannel ch, int ops, Object att) {
36      super();
37      this.chann = ch;
38      this.sel = selector;
39      this.ops = ops; // FIXME check
40  
41      if (ch instanceof AFDatagramChannel<?>) {
42        this.core = ((AFDatagramChannel<?>) ch).getAFCore();
43      } else if (ch instanceof AFSocketChannel<?>) {
44        this.core = ((AFSocketChannel<?>) ch).getAFCore();
45      } else if (ch instanceof AFServerSocketChannel<?>) {
46        this.core = ((AFServerSocketChannel<?>) ch).getAFCore();
47      } else {
48        throw new UnsupportedOperationException("Unsupported channel: " + ch);
49      }
50  
51      attach(att);
52    }
53  
54    @Override
55    public SelectableChannel channel() {
56      return chann;
57    }
58  
59    @Override
60    public Selector selector() {
61      return sel;
62    }
63  
64    @Override
65    public boolean isValid() {
66      return !hasOpInvalid() && !cancelled.get() && chann.isOpen() && sel.isOpen();
67    }
68  
69    boolean isCancelled() {
70      return cancelled.get();
71    }
72  
73    boolean hasOpInvalid() {
74      return (opsReady & OP_INVALID) != 0;
75    }
76  
77    boolean isSelected() {
78      return readyOps() != 0;
79    }
80  
81    @Override
82    public void cancel() {
83      sel.remove(this);
84      cancelNoRemove();
85    }
86  
87    void cancelNoRemove() {
88      if (!cancelled.compareAndSet(false, true) || !chann.isOpen()) {
89        return;
90      }
91  
92      cancel1();
93    }
94  
95    private void cancel1() {
96      // FIXME
97    }
98  
99    @Override
100   public int interestOps() {
101     return ops;
102   }
103 
104   @Override
105   public SelectionKey interestOps(int interestOps) {
106     this.ops = interestOps; // FIXME check
107     return this;
108   }
109 
110   @Override
111   public int readyOps() {
112     return opsReady & ~OP_INVALID;
113   }
114 
115   AFSocketCore getAFCore() {
116     return core;
117   }
118 
119   void setOpsReady(int opsReady) {
120     this.opsReady = opsReady;
121   }
122 
123   @Override
124   public String toString() {
125     return super.toString() + "[" + readyOps() + ";valid=" + isValid() + ";channel=" + channel()
126         + "]";
127   }
128 }