private void invokeOnComplete ( ) { for ( ; ; ) { if ( pooledBuffers != null ) { for ( PooledByteBuffer buffer : pooledBuffers ) { buffer . close ( ) ; } pooledBuffers = null ; } IoCallback callback = this . callback ; this . buffer = null ; this . fileChannel = null ; this . callback = null ; inCallback = true ; try { callback . onComplete ( exchange , this ) ; } finally { inCallback = false ; } StreamSinkChannel channel = this . channel ; if ( this . buffer != null ) { long t = Buffers . remaining ( buffer ) ; final long total = t ; long written = 0 ; try { do { long res = channel . write ( buffer ) ; written += res ; if ( res == 0 ) { if ( writeListener == null ) { initWriteListener ( ) ; } channel . getWriteSetter ( ) . set ( writeListener ) ; channel . resumeWrites ( ) ; return ; } } while ( written < total ) ; //we loop and invoke onComplete again } catch ( IOException e ) { invokeOnException ( callback , e ) ; } } else if ( this . fileChannel != null ) { if ( transferTask == null ) { transferTask = new TransferTask ( ) ; } if ( ! transferTask . run ( false ) ) { return ; } } else { return ; } } }
Invokes the onComplete method . If send is called again in onComplete then we loop and write it out . This prevents possible stack overflows due to recursion