/// <summary> /// Cancels all outstanding I/O operations. /// </summary> private void CancelOperations() { // cancel any outstanding write operations. WriteOperation operation = null; do { operation = null; lock (m_writeQueue) { if (m_writeQueue.Count > 0) { operation = m_writeQueue.First.Value; m_writeQueue.RemoveFirst(); } } if (operation != null) { operation.Fault(StatusCodes.BadConnectionClosed); } } while (operation != null); // cancel any outstanding read operations. byte[] buffer = null; do { buffer = null; lock (m_readQueue) { if (m_readQueue.Count > 0) { buffer = m_readQueue.First.Value.Array; m_readQueue.RemoveFirst(); // check for graceful shutdown. if (buffer != null) { BufferManager.UnlockBuffer(buffer); #if TRACK_MEMORY int cookie = BitConverter.ToInt32(buffer, 0); if (cookie < 0) { Utils.Trace("BufferCookieError (CancelOperations): Cookie={0:X8}", cookie); } #endif } } } if (buffer != null) { m_bufferManager.ReturnBuffer(buffer, "CancelOperations"); } } while (buffer != null); }
/// <summary> /// Write a single message. /// </summary> private void WriteMessage(WriteOperation operation) { // get the buffers to write. BufferCollection buffers = operation.ChunksToSend; // get the socket. Socket socket = null; lock (m_socketLock) { socket = m_socket; } // check if the socket has been closed. if (socket == null) { operation.Fault(ServiceResult.Create(StatusCodes.BadConnectionClosed, "Socket is no longer available.")); return; } // begin the write operation (blocks until data is copied into the transport buffer). try { int bytesSent = socket.Send(buffers, SocketFlags.None); // check that all the data was sent. if (bytesSent < buffers.TotalSize) { operation.Fault(ServiceResult.Create(StatusCodes.BadConnectionClosed, "Write operation could not complete.")); return; } // everything ok - yeah!. operation.Complete(bytesSent); } catch (Exception e) { operation.Fault(ServiceResult.Create(e, StatusCodes.BadConnectionClosed, "Write to socket failed.")); } }
/// <summary> /// Sends a request to the server. /// </summary> private void SendRequest(WriteOperation operation, int timeout, IServiceRequest request) { bool success = false; BufferCollection buffers = null; try { // check for valid token. TcpChannelToken token = CurrentToken; if (token == null) { throw new ServiceResultException(StatusCodes.BadSecureChannelClosed); } // must return an error to the client if limits are exceeded. bool limitsExceeded = false; buffers = WriteSymmetricMessage( TcpMessageType.Message, operation.RequestId, token, request, true, out limitsExceeded); BeginWriteMessage(buffers, timeout, operation); buffers = null; success = true; if (limitsExceeded) { throw new ServiceResultException(StatusCodes.BadRequestTooLarge); } } catch (Exception e) { operation.Fault(e, StatusCodes.BadRequestInterrupted, "Could not send request to server."); } finally { if (buffers != null) { buffers.Release(BufferManager, "SendRequest"); } if (!success) { OperationCompleted(operation); } } }