42 import com.sun.nio.sctp.SctpSocketOption;
43 import com.sun.nio.sctp.SctpStandardSocketOptions;
44 import sun.nio.ch.NativeThread;
45 import sun.nio.ch.IOStatus;
46 import sun.nio.ch.IOUtil;
47 import sun.nio.ch.Net;
48 import sun.nio.ch.SelChImpl;
49 import sun.nio.ch.SelectionKeyImpl;
50
51 /**
52 * An implementation of SctpServerChannel
53 */
54 public class SctpServerChannelImpl extends SctpServerChannel
55 implements SelChImpl
56 {
57 private final FileDescriptor fd;
58
59 private final int fdVal;
60
61 /* IDs of native thread doing accept, for signalling */
62 private volatile long thread;
63
64 /* Lock held by thread currently blocked in this channel */
65 private final Object lock = new Object();
66
67 /* Lock held by any thread that modifies the state fields declared below
68 * DO NOT invoke a blocking I/O operation while holding this lock! */
69 private final Object stateLock = new Object();
70
71 private enum ChannelState {
72 UNINITIALIZED,
73 INUSE,
74 KILLPENDING,
75 KILLED,
76 }
77 /* -- The following fields are protected by stateLock -- */
78 private ChannelState state = ChannelState.UNINITIALIZED;
79
80 /* Binding: Once bound the port will remain constant. */
81 int port = -1;
82 private final HashSet<InetSocketAddress> localAddresses = new HashSet<>();
183 for (InetSocketAddress addr : localAddresses) {
184 if (addr.getAddress().equals(address)) {
185 localAddresses.remove(addr);
186 break;
187 }
188 }
189 }
190 }
191 }
192 return this;
193 }
194
195 private boolean isBound() {
196 synchronized (stateLock) {
197 return port != -1;
198 }
199 }
200
201 private void acceptCleanup() throws IOException {
202 synchronized (stateLock) {
203 thread = 0;
204 if (state == ChannelState.KILLPENDING)
205 kill();
206 }
207 }
208
209 @Override
210 public SctpChannel accept() throws IOException {
211 synchronized (lock) {
212 if (!isOpen())
213 throw new ClosedChannelException();
214 if (!isBound())
215 throw new NotYetBoundException();
216
217 int n = 0;
218 FileDescriptor newfd = new FileDescriptor();
219 InetSocketAddress[] isaa = new InetSocketAddress[1];
220
221 try {
222 begin();
223 if (!isOpen())
236 }
237
238 if (n < 1)
239 return null;
240
241 IOUtil.configureBlocking(newfd, true);
242 return new SctpChannelImpl(provider(), newfd);
243 }
244 }
245
246 @Override
247 protected void implConfigureBlocking(boolean block) throws IOException {
248 IOUtil.configureBlocking(fd, block);
249 }
250
251 @Override
252 public void implCloseSelectableChannel() throws IOException {
253 synchronized (stateLock) {
254 if (state != ChannelState.KILLED)
255 SctpNet.preClose(fdVal);
256 if (thread != 0)
257 NativeThread.signal(thread);
258 if (!isRegistered())
259 kill();
260 }
261 }
262
263 @Override
264 public void kill() throws IOException {
265 synchronized (stateLock) {
266 if (state == ChannelState.KILLED)
267 return;
268 if (state == ChannelState.UNINITIALIZED) {
269 state = ChannelState.KILLED;
270 SctpNet.close(fdVal);
271 return;
272 }
273 assert !isOpen() && !isRegistered();
274
275 // Postpone the kill if there is a thread in accept
276 if (thread == 0) {
277 state = ChannelState.KILLED;
278 SctpNet.close(fdVal);
279 } else {
280 state = ChannelState.KILLPENDING;
281 }
282 }
283 }
284
285 @Override
286 public FileDescriptor getFD() {
287 return fd;
288 }
289
290 @Override
291 public int getFDVal() {
292 return fdVal;
293 }
294
295 /**
296 * Translates native poll revent ops into a ready operation ops
|
42 import com.sun.nio.sctp.SctpSocketOption;
43 import com.sun.nio.sctp.SctpStandardSocketOptions;
44 import sun.nio.ch.NativeThread;
45 import sun.nio.ch.IOStatus;
46 import sun.nio.ch.IOUtil;
47 import sun.nio.ch.Net;
48 import sun.nio.ch.SelChImpl;
49 import sun.nio.ch.SelectionKeyImpl;
50
51 /**
52 * An implementation of SctpServerChannel
53 */
54 public class SctpServerChannelImpl extends SctpServerChannel
55 implements SelChImpl
56 {
57 private final FileDescriptor fd;
58
59 private final int fdVal;
60
61 /* IDs of native thread doing accept, for signalling */
62 private volatile NativeThread thread;
63
64 /* Lock held by thread currently blocked in this channel */
65 private final Object lock = new Object();
66
67 /* Lock held by any thread that modifies the state fields declared below
68 * DO NOT invoke a blocking I/O operation while holding this lock! */
69 private final Object stateLock = new Object();
70
71 private enum ChannelState {
72 UNINITIALIZED,
73 INUSE,
74 KILLPENDING,
75 KILLED,
76 }
77 /* -- The following fields are protected by stateLock -- */
78 private ChannelState state = ChannelState.UNINITIALIZED;
79
80 /* Binding: Once bound the port will remain constant. */
81 int port = -1;
82 private final HashSet<InetSocketAddress> localAddresses = new HashSet<>();
183 for (InetSocketAddress addr : localAddresses) {
184 if (addr.getAddress().equals(address)) {
185 localAddresses.remove(addr);
186 break;
187 }
188 }
189 }
190 }
191 }
192 return this;
193 }
194
195 private boolean isBound() {
196 synchronized (stateLock) {
197 return port != -1;
198 }
199 }
200
201 private void acceptCleanup() throws IOException {
202 synchronized (stateLock) {
203 thread = null;
204 if (state == ChannelState.KILLPENDING)
205 kill();
206 }
207 }
208
209 @Override
210 public SctpChannel accept() throws IOException {
211 synchronized (lock) {
212 if (!isOpen())
213 throw new ClosedChannelException();
214 if (!isBound())
215 throw new NotYetBoundException();
216
217 int n = 0;
218 FileDescriptor newfd = new FileDescriptor();
219 InetSocketAddress[] isaa = new InetSocketAddress[1];
220
221 try {
222 begin();
223 if (!isOpen())
236 }
237
238 if (n < 1)
239 return null;
240
241 IOUtil.configureBlocking(newfd, true);
242 return new SctpChannelImpl(provider(), newfd);
243 }
244 }
245
246 @Override
247 protected void implConfigureBlocking(boolean block) throws IOException {
248 IOUtil.configureBlocking(fd, block);
249 }
250
251 @Override
252 public void implCloseSelectableChannel() throws IOException {
253 synchronized (stateLock) {
254 if (state != ChannelState.KILLED)
255 SctpNet.preClose(fdVal);
256 if (NativeThread.isNativeThread(thread))
257 thread.signal();
258 if (!isRegistered())
259 kill();
260 }
261 }
262
263 @Override
264 public void kill() throws IOException {
265 synchronized (stateLock) {
266 if (state == ChannelState.KILLED)
267 return;
268 if (state == ChannelState.UNINITIALIZED) {
269 state = ChannelState.KILLED;
270 SctpNet.close(fdVal);
271 return;
272 }
273 assert !isOpen() && !isRegistered();
274
275 // Postpone the kill if there is a thread in accept
276 if (thread == null) {
277 state = ChannelState.KILLED;
278 SctpNet.close(fdVal);
279 } else {
280 state = ChannelState.KILLPENDING;
281 }
282 }
283 }
284
285 @Override
286 public FileDescriptor getFD() {
287 return fd;
288 }
289
290 @Override
291 public int getFDVal() {
292 return fdVal;
293 }
294
295 /**
296 * Translates native poll revent ops into a ready operation ops
|