protected VirtualConnection write(long _numBytes, TCPWriteCompletedCallback userCallback,
                                      boolean forceQueue, int timeout, boolean fromQueue) {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "writeAsync, numBytes=" + _numBytes + ", timeout=" + timeout
                         + ", fromQueue=" + fromQueue + ", vc=" + getVCHash());
        }
        VirtualConnection vc = null;
        try {
            long numBytes = _numBytes;

            // Handle timing out of former read request.
            if (timeout == IMMED_TIMEOUT || timeout == ABORT_TIMEOUT) {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "Requested to timeout former request.  Calling device side.");
                }
                getConnLink().getDeviceWriteInterface().write(numBytes, this, forceQueue, timeout);
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                    Tr.exit(tc, "writeAsync: " + getVC());
                }
                return getVC();
            }

            // Look for errors in the request.
            IOException exceptionInRequest = checkForErrors(numBytes, true);
            if (exceptionInRequest != null) {
                // Found an error.
                boolean fireHere = true;
                if (forceQueue) {
                    // Error must be returned on a separate thread.
                    queuedWork.setErrorParameters(getConnLink().getVirtualConnection(),
                                                this, userCallback, exceptionInRequest);

                    EventEngine events = SSLChannelProvider.getEventService();
                    if (null == events) {
                        Exception e = new Exception("missing event admin");
                        FFDCFilter.processException(e, getClass().getName(), "172", this);
                        // fall-thru below and use callback here regardless
                    } else {
                        // fire an event to continue this queued work
                        Event event = events.createEvent(SSLEventHandler.TOPIC_QUEUED_WORK);
                        event.setProperty(SSLEventHandler.KEY_RUNNABLE, this.queuedWork);
                        events.postEvent(event);
                        fireHere = false;
                    }
                }
                if (fireHere) {
                    // Call the callback on this thread.
                    userCallback.error(getConnLink().getVirtualConnection(), this, exceptionInRequest);
                }
                // Return null indicating that the callback will handle the response.
                return null;
            }

            // Get the work on another thread if queuing is being forced.
            if (forceQueue) {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "Forcing write request to another thread, vc=" + getVCHash());
                }
                queuedWork.setWriteParameters(numBytes, userCallback, timeout);

                EventEngine events = SSLChannelProvider.getEventService();
                if (null == events) {
                    IOException e = new IOException("missing event admin");
                    FFDCFilter.processException(e, getClass().getName(), "471", this);
                    userCallback.error(getConnLink().getVirtualConnection(), this, e);
                } else {
                    // fire an event to continue this queued work
                    Event event = events.createEvent(SSLEventHandler.TOPIC_QUEUED_WORK);
                    event.setProperty(SSLEventHandler.KEY_RUNNABLE, this.queuedWork);
                    events.postEvent(event);
                }
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                    Tr.exit(tc, "writeAsync: null");
                }
                return null;
            }

            callback = userCallback;

            // Adjust size of numBytes if all data is requested to be written (-1).
            if (numBytes == TCPWriteRequestContext.WRITE_ALL_DATA) {
                numBytes = WsByteBufferUtils.lengthOf(getBuffers());
            }

            SSLEngineResult sslResult = null;

            // Check if a handshake is needed.
            if (SSLUtils.isHandshaking(getConnLink().getSSLEngine())) {
                // A handshake is needed. Set the write parameters.
                handshakeCallback.setWriteParameters(numBytes, timeout);
                try {
                    sslResult = doHandshake(handshakeCallback);
                } catch (IOException e) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "Caught exception during SSL handshake, " + e);
                    }
                    callback.error(getConnLink().getVirtualConnection(), this, e);
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                        Tr.exit(tc, "writeAsynch: null");
                    }
                    return null;
                }
                // Check to see if handshake was done synchronously.
                if (sslResult != null) {
                    // Handshake was done synchronously. Verify results.
                    if (sslResult.getHandshakeStatus() != HandshakeStatus.FINISHED) {
                        IOException e = new IOException("Unable to complete SSLhandshake");
                        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                            Tr.debug(tc, "Unable to complete SSLhandshake, " + e);
                        }
                        callback.error(getConnLink().getVirtualConnection(), this, e);
                            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                            Tr.exit(tc, "writeAsynch: null");
                        }
                        return null;
                    }
                } else {
                    // Handshake is being handled asynchronously.
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                        Tr.exit(tc, "writeAsynch: null");
                    }
                    return null;
                }
            }

            // Code can only get here if handshake wasn't needed or was done sync with valid return code.
            // Encrypt the data and write it to the network.
            vc = encryptAndWriteAsync(numBytes, false, timeout);

            // If data is ready, but this was from a formerly queued request, call the callback.
            if (vc != null && fromQueue) {
                callback.complete(vc, this);
                vc = null;
            }
        } catch (Exception original) {
            synchronized (closeSync) {
                // if close has been called then assume this exception was due to a race condition
                // with the close logic. so no FFDC here.
                if (closeCalled) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "Cannot write, the link was already closed; vc=" +this.getVCHash());
                    }
                    return null;
                } else {
                    IOException ioe;
                    if (original instanceof IOException) {
                        ioe = (IOException) original;
                    }
                    ioe = new IOException("writeAsynch failed with exception: " +original.getMessage());
                    boolean fireHere = true;
                    if (forceQueue) {
                        // Error must be returned on a separate thread.
                        queuedWork.setErrorParameters(getConnLink().getVirtualConnection(),
                                                    this, userCallback, ioe);
                        EventEngine events = SSLChannelProvider.getEventService();
                        if (null != events) {
                            // fire an event to continue this queued work
                            Event event = events.createEvent(SSLEventHandler.TOPIC_QUEUED_WORK);
                            event.setProperty(SSLEventHandler.KEY_RUNNABLE, this.queuedWork);
                            events.postEvent(event);
                            fireHere = false;
                        }
                    }
                    if (fireHere) {
                        // Call the callback on this thread.
                        userCallback.error(getConnLink().getVirtualConnection(), this, ioe);
                    }
                    return null;
                }
            }
        }
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "writeAsynch: " + vc);
        }
        return vc;
    }
protected VirtualConnection write ( long _numBytes , TCPWriteCompletedCallback userCallback , boolean forceQueue , int timeout , boolean fromQueue ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . entry ( tc , "writeAsync, numBytes=" + _numBytes + ", timeout=" + timeout + ", fromQueue=" + fromQueue + ", vc=" + getVCHash ( ) ) ; } VirtualConnection vc = null ; try { long numBytes = _numBytes ; if ( timeout == IMMED_TIMEOUT || timeout == ABORT_TIMEOUT ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Requested to timeout former request.  Calling device side." ) ; } getConnLink ( ) . getDeviceWriteInterface ( ) . write ( numBytes , this , forceQueue , timeout ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsync: " + getVC ( ) ) ; } return getVC ( ) ; } IOException exceptionInRequest = checkForErrors ( numBytes , true ) ; if ( exceptionInRequest != null ) { boolean fireHere = true ; if ( forceQueue ) { queuedWork . setErrorParameters ( getConnLink ( ) . getVirtualConnection ( ) , this , userCallback , exceptionInRequest ) ; EventEngine events = SSLChannelProvider . getEventService ( ) ; if ( null == events ) { Exception e = new Exception ( "missing event admin" ) ; FFDCFilter . processException ( e , getClass ( ) . getName ( ) , "172" , this ) ; } else { Event event = events . createEvent ( SSLEventHandler . TOPIC_QUEUED_WORK ) ; event . setProperty ( SSLEventHandler . KEY_RUNNABLE , this . queuedWork ) ; events . postEvent ( event ) ; fireHere = false ; } } if ( fireHere ) { userCallback . error ( getConnLink ( ) . getVirtualConnection ( ) , this , exceptionInRequest ) ; } return null ; } if ( forceQueue ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Forcing write request to another thread, vc=" + getVCHash ( ) ) ; } queuedWork . setWriteParameters ( numBytes , userCallback , timeout ) ; EventEngine events = SSLChannelProvider . getEventService ( ) ; if ( null == events ) { IOException e = new IOException ( "missing event admin" ) ; FFDCFilter . processException ( e , getClass ( ) . getName ( ) , "471" , this ) ; userCallback . error ( getConnLink ( ) . getVirtualConnection ( ) , this , e ) ; } else { Event event = events . createEvent ( SSLEventHandler . TOPIC_QUEUED_WORK ) ; event . setProperty ( SSLEventHandler . KEY_RUNNABLE , this . queuedWork ) ; events . postEvent ( event ) ; } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsync: null" ) ; } return null ; } callback = userCallback ; if ( numBytes == TCPWriteRequestContext . WRITE_ALL_DATA ) { numBytes = WsByteBufferUtils . lengthOf ( getBuffers ( ) ) ; } SSLEngineResult sslResult = null ; if ( SSLUtils . isHandshaking ( getConnLink ( ) . getSSLEngine ( ) ) ) { handshakeCallback . setWriteParameters ( numBytes , timeout ) ; try { sslResult = doHandshake ( handshakeCallback ) ; } catch ( IOException e ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Caught exception during SSL handshake, " + e ) ; } callback . error ( getConnLink ( ) . getVirtualConnection ( ) , this , e ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsynch: null" ) ; } return null ; } if ( sslResult != null ) { if ( sslResult . getHandshakeStatus ( ) != HandshakeStatus . FINISHED ) { IOException e = new IOException ( "Unable to complete SSLhandshake" ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Unable to complete SSLhandshake, " + e ) ; } callback . error ( getConnLink ( ) . getVirtualConnection ( ) , this , e ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsynch: null" ) ; } return null ; } } else { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsynch: null" ) ; } return null ; } } vc = encryptAndWriteAsync ( numBytes , false , timeout ) ; if ( vc != null && fromQueue ) { callback . complete ( vc , this ) ; vc = null ; } } catch ( Exception original ) { synchronized ( closeSync ) { if ( closeCalled ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Cannot write, the link was already closed; vc=" + this . getVCHash ( ) ) ; } return null ; } else { IOException ioe ; if ( original instanceof IOException ) { ioe = ( IOException ) original ; } ioe = new IOException ( "writeAsynch failed with exception: " + original . getMessage ( ) ) ; boolean fireHere = true ; if ( forceQueue ) { queuedWork . setErrorParameters ( getConnLink ( ) . getVirtualConnection ( ) , this , userCallback , ioe ) ; EventEngine events = SSLChannelProvider . getEventService ( ) ; if ( null != events ) { Event event = events . createEvent ( SSLEventHandler . TOPIC_QUEUED_WORK ) ; event . setProperty ( SSLEventHandler . KEY_RUNNABLE , this . queuedWork ) ; events . postEvent ( event ) ; fireHere = false ; } } if ( fireHere ) { userCallback . error ( getConnLink ( ) . getVirtualConnection ( ) , this , ioe ) ; } return null ; } } } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) { Tr . exit ( tc , "writeAsynch: " + vc ) ; } return vc ; }
See method above. Extra parameter tells if the request was from a formerly queued request.

@param _numBytes
@param userCallback
@param forceQueue
@param timeout
@param fromQueue
@return VirtualConnection