94 private static final int ST_CONNECTIONPENDING = 1; |
94 private static final int ST_CONNECTIONPENDING = 1; |
95 private static final int ST_CONNECTED = 2; |
95 private static final int ST_CONNECTED = 2; |
96 private static final int ST_CLOSING = 3; |
96 private static final int ST_CLOSING = 3; |
97 private static final int ST_KILLPENDING = 4; |
97 private static final int ST_KILLPENDING = 4; |
98 private static final int ST_KILLED = 5; |
98 private static final int ST_KILLED = 5; |
99 private int state; |
99 private volatile int state; // need stateLock to change |
100 |
100 |
101 // IDs of native threads doing reads and writes, for signalling |
101 // IDs of native threads doing reads and writes, for signalling |
102 private long readerThread; |
102 private long readerThread; |
103 private long writerThread; |
103 private long writerThread; |
104 |
104 |
572 return this; |
572 return this; |
573 } |
573 } |
574 |
574 |
575 @Override |
575 @Override |
576 public boolean isConnected() { |
576 public boolean isConnected() { |
577 synchronized (stateLock) { |
577 return (state == ST_CONNECTED); |
578 return (state == ST_CONNECTED); |
|
579 } |
|
580 } |
578 } |
581 |
579 |
582 @Override |
580 @Override |
583 public boolean isConnectionPending() { |
581 public boolean isConnectionPending() { |
584 synchronized (stateLock) { |
582 return (state == ST_CONNECTIONPENDING); |
585 return (state == ST_CONNECTIONPENDING); |
|
586 } |
|
587 } |
583 } |
588 |
584 |
589 /** |
585 /** |
590 * Marks the beginning of a connect operation that might block. |
586 * Marks the beginning of a connect operation that might block. |
591 * @param blocking true if configured blocking |
587 * @param blocking true if configured blocking |
602 // set hook for Thread.interrupt |
598 // set hook for Thread.interrupt |
603 begin(); |
599 begin(); |
604 } |
600 } |
605 synchronized (stateLock) { |
601 synchronized (stateLock) { |
606 ensureOpen(); |
602 ensureOpen(); |
|
603 int state = this.state; |
607 if (state == ST_CONNECTED) |
604 if (state == ST_CONNECTED) |
608 throw new AlreadyConnectedException(); |
605 throw new AlreadyConnectedException(); |
609 if (state == ST_CONNECTIONPENDING) |
606 if (state == ST_CONNECTIONPENDING) |
610 throw new ConnectionPendingException(); |
607 throw new ConnectionPendingException(); |
611 assert state == ST_UNCONNECTED; |
608 assert state == ST_UNCONNECTED; |
612 state = ST_CONNECTIONPENDING; |
609 this.state = ST_CONNECTIONPENDING; |
613 |
610 |
614 if (localAddress == null) |
611 if (localAddress == null) |
615 NetHooks.beforeTcpConnect(fd, isa.getAddress(), isa.getPort()); |
612 NetHooks.beforeTcpConnect(fd, isa.getAddress(), isa.getPort()); |
616 remoteAddress = isa; |
613 remoteAddress = isa; |
617 |
614 |
983 newOps = intOps; |
980 newOps = intOps; |
984 sk.nioReadyOps(newOps); |
981 sk.nioReadyOps(newOps); |
985 return (newOps & ~oldOps) != 0; |
982 return (newOps & ~oldOps) != 0; |
986 } |
983 } |
987 |
984 |
|
985 boolean connected = isConnected(); |
988 if (((ops & Net.POLLIN) != 0) && |
986 if (((ops & Net.POLLIN) != 0) && |
989 ((intOps & SelectionKey.OP_READ) != 0) && |
987 ((intOps & SelectionKey.OP_READ) != 0) && connected) |
990 (state == ST_CONNECTED)) |
|
991 newOps |= SelectionKey.OP_READ; |
988 newOps |= SelectionKey.OP_READ; |
992 |
989 |
993 if (((ops & Net.POLLCONN) != 0) && |
990 if (((ops & Net.POLLCONN) != 0) && |
994 ((intOps & SelectionKey.OP_CONNECT) != 0) && |
991 ((intOps & SelectionKey.OP_CONNECT) != 0) && isConnectionPending()) |
995 ((state == ST_UNCONNECTED) || (state == ST_CONNECTIONPENDING))) { |
|
996 newOps |= SelectionKey.OP_CONNECT; |
992 newOps |= SelectionKey.OP_CONNECT; |
997 } |
|
998 |
993 |
999 if (((ops & Net.POLLOUT) != 0) && |
994 if (((ops & Net.POLLOUT) != 0) && |
1000 ((intOps & SelectionKey.OP_WRITE) != 0) && |
995 ((intOps & SelectionKey.OP_WRITE) != 0) && connected) |
1001 (state == ST_CONNECTED)) |
|
1002 newOps |= SelectionKey.OP_WRITE; |
996 newOps |= SelectionKey.OP_WRITE; |
1003 |
997 |
1004 sk.nioReadyOps(newOps); |
998 sk.nioReadyOps(newOps); |
1005 return (newOps & ~oldOps) != 0; |
999 return (newOps & ~oldOps) != 0; |
1006 } |
1000 } |