예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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."));
            }
        }
예제 #3
0
        /// <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);
                }
            }
        }