1616import java .util .ArrayList ;
1717import java .util .Iterator ;
1818import java .util .List ;
19+ import java .util .concurrent .ExecutionException ;
1920import java .util .concurrent .ExecutorService ;
2021import java .util .concurrent .Future ;
2122
@@ -48,16 +49,20 @@ public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel {
4849
4950 protected SSLEngineResult res ;
5051 protected SSLEngine sslEngine ;
52+ protected final boolean isblocking ;
53+
54+ public SSLSocketChannel2 ( SocketChannel channel , SSLEngine sslEngine , ExecutorService exec , SelectionKey key ) throws IOException {
55+ this .sc = channel ;
5156
52- public SSLSocketChannel2 ( SelectionKey key , SSLEngine sslEngine , ExecutorService exec ) throws IOException {
53- this .sc = (SocketChannel ) key .channel ();
54- this .key = key ;
5557 this .sslEngine = sslEngine ;
5658 this .exec = exec ;
5759
5860 tasks = new ArrayList <Future <?>>( 3 );
59-
60- this .key .interestOps ( key .interestOps () | SelectionKey .OP_WRITE );
61+ if ( key != null ) {
62+ key .interestOps ( key .interestOps () | SelectionKey .OP_WRITE );
63+ this .key = key ;
64+ }
65+ isblocking = channel .isBlocking ();
6166
6267 sslEngine .setEnableSessionCreation ( true );
6368 SSLSession session = sslEngine .getSession ();
@@ -67,14 +72,34 @@ public SSLSocketChannel2( SelectionKey key , SSLEngine sslEngine , ExecutorServi
6772 processHandshake ();
6873 }
6974
70- private void processHandshake () throws IOException {
75+ private void consumeFutureUninterruptible ( Future <?> f ) {
76+ try {
77+ boolean interrupted = false ;
78+ while ( true ) {
79+ try {
80+ f .get ();
81+ break ;
82+ } catch ( InterruptedException e ) {
83+ interrupted = true ;
84+ }
85+ }
86+ if ( interrupted )
87+ Thread .currentThread ().interrupt ();
88+ } catch ( ExecutionException e ) {
89+ throw new RuntimeException ( e );
90+ }
91+ }
92+
93+ private synchronized void processHandshake () throws IOException {
7194 if ( !tasks .isEmpty () ) {
7295 Iterator <Future <?>> it = tasks .iterator ();
7396 while ( it .hasNext () ) {
7497 Future <?> f = it .next ();
7598 if ( f .isDone () ) {
7699 it .remove ();
77100 } else {
101+ if ( isBlocking () )
102+ consumeFutureUninterruptible ( f );
78103 return ;
79104 }
80105 }
@@ -106,11 +131,11 @@ private synchronized ByteBuffer wrap( ByteBuffer b ) throws SSLException {
106131
107132 private synchronized ByteBuffer unwrap () throws SSLException {
108133 int rem ;
109- do {
134+ do {
110135 rem = inData .remaining ();
111136 res = sslEngine .unwrap ( inCrypt , inData );
112137 } while ( rem != inData .remaining () );
113-
138+
114139 inData .flip ();
115140 return inData ;
116141 }
@@ -146,9 +171,17 @@ public int write( ByteBuffer src ) throws IOException {
146171 }
147172
148173 public int read ( ByteBuffer dst ) throws IOException {
149- if ( !isHandShakeComplete () ) {
150- processHandshake ();
174+ if ( !dst .hasRemaining () )
151175 return 0 ;
176+ if ( isBlocking () ) {
177+ while ( !isHandShakeComplete () ) {
178+ processHandshake ();
179+ }
180+ } else {
181+ processHandshake ();
182+ if ( !isHandShakeComplete () ) {
183+ return 0 ;
184+ }
152185 }
153186
154187 int purged = readRemaining ( dst );
@@ -173,8 +206,6 @@ public int read( ByteBuffer dst ) throws IOException {
173206 }
174207
175208 private int readRemaining ( ByteBuffer dst ) throws SSLException {
176- assert ( dst .hasRemaining () );
177-
178209 if ( inData .hasRemaining () ) {
179210 return transfereTo ( inData , dst );
180211 }
@@ -269,4 +300,9 @@ private int transfereTo( ByteBuffer from, ByteBuffer to ) {
269300
270301 }
271302
303+ @ Override
304+ public boolean isBlocking () {
305+ return isblocking ;
306+ }
307+
272308}
0 commit comments