internal void ProcessRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { // invariant: only one thread processing the first 3 statments at one instance in time // (statement nr 3 can lead to a next read allowing another i/o completion thread // to call this method) try { // call is serialised, no need for a lock; at most one thread is reading messages from transport. Interlocked.Increment(ref m_requestsInProgress); m_msgReceiveTask = receiveTask; m_receiver.ProcessRequest(requestStream, m_serverCon); // in the mean time, deserialise request notification may have been sent. // -> multiple requests are possible in progress and execute the following code int receivePending = Interlocked.Exchange(ref m_receivePending, NO_RECEIVE_PENDING); Interlocked.Decrement(ref m_requestsInProgress); // ReceivePending will be again set to true, when a request has been deserialised // and too many requests are processing if (receivePending == RECEIVE_PENDING) { // too many requests in parallel last time when trying to start receive // in NotifyDeserialiseRequestComplete -> do it now StartReadNextMessage(); } } catch (Exception ex) { HandleUnexpectedProcessingException(); Trace.WriteLine("stopped processing on server connection after unexpected exception: " + ex); } }
/// <summary> /// begins receiving messages asynchronously /// </summary> internal void StartMessageReception() { lock (this) { if (m_messageReceiveTask == null) { m_messageReceiveTask = new MessageReceiveTask(m_transport, this); m_messageReceiveTask.StartReceiveMessage(); } // else ignore, already started } }
/// <summary> /// processes this locate reqeuest message /// </summary> private void ProcessLocateRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { lock (this) { if (m_reiceivedRequestDispatcher == null) { SendErrorResponseMessage(); // can't be handled, no dispatcher return; } } m_reiceivedRequestDispatcher.ProcessLocateRequestMessage(requestStream, receiveTask); }
internal void ProcessLocateRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { // this called is completely handled by IIOP.NET // -> no servant will be called and therefore whole request is processed before reading next message try { m_receiver.ProcessLocateRequest(requestStream, m_serverCon); receiveTask.StartReceiveMessage(); } catch (Exception ex) { HandleUnexpectedProcessingException(); Trace.WriteLine("stopped processing on server connection after unexpected exception: " + ex); } }
internal void MsgReceivedCallback(MessageReceiveTask messageReceived) { Stream messageStream = messageReceived.MessageStream; GiopHeader header = messageReceived.Header; if (FragmentedMessageAssembler.IsFragmentedMessage(header)) { // defragment if (FragmentedMessageAssembler.IsStartFragment(header)) { m_fragmentAssembler.StartFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else if (!FragmentedMessageAssembler.IsLastFragment(header)) { m_fragmentAssembler.AddFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else { messageStream = m_fragmentAssembler.FinishFragmentedMsg(messageStream, out header); } } // here, the message is no longer fragmented, don't check for fragment here switch (header.GiopType) { case GiopMsgTypes.Request: ProcessRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.LocateRequest: ProcessLocateRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.Reply: // see, if somebody is interested in the response lock (m_waitingForResponse.SyncRoot) { uint replyForRequestId = ExtractRequestIdFromReplyMessage(messageStream); IResponseWaiter waiter = (IResponseWaiter)m_waitingForResponse[replyForRequestId]; if (waiter != null) { m_waitingForResponse.Remove(replyForRequestId); waiter.Response = messageStream; waiter.Notify(); } else { Debug.WriteLine("received not expected reply for request with id " + replyForRequestId); } } messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.LocateReply: // ignore, not interesting messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.CloseConnection: CloseConnection(); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; case GiopMsgTypes.CancelRequest: CdrInputStreamImpl input = new CdrInputStreamImpl(messageStream); GiopHeader cancelHeader = new GiopHeader(input); uint requestIdToCancel = input.ReadULong(); m_fragmentAssembler.CancelFragmentsIfInProgress(requestIdToCancel); messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.MessageError: CloseConnectionAfterUnexpectedException(new MARSHAL(16, CompletionStatus.Completed_MayBe)); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; default: // should not occur; // hint: fragment is also considered as error here, // because fragment should be handled before this loop // send message error SendErrorResponseMessage(); messageReceived.StartReceiveMessage(); // receive next message break; } }
/// <summary> /// abort receiving messages /// </summary> private void StopMessageReception() { lock (this) { m_messageReceiveTask = null; } }
internal void MsgReceivedCallback(MessageReceiveTask messageReceived) { Stream messageStream = messageReceived.MessageStream; GiopHeader header = messageReceived.Header; if (FragmentedMessageAssembler.IsFragmentedMessage(header)) { // defragment if (FragmentedMessageAssembler.IsStartFragment(header)) { m_fragmentAssembler.StartFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else if (!FragmentedMessageAssembler.IsLastFragment(header)) { m_fragmentAssembler.AddFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else { messageStream = m_fragmentAssembler.FinishFragmentedMsg(messageStream, out header); } } // here, the message is no longer fragmented, don't check for fragment here switch (header.GiopType) { case GiopMsgTypes.Request: ProcessRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.LocateRequest: ProcessLocateRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.Reply: // see, if somebody is interested in the response lock (m_waitingForResponse.SyncRoot) { uint replyForRequestId = ExtractRequestIdFromReplyMessage(messageStream); IResponseWaiter waiter = (IResponseWaiter)m_waitingForResponse[replyForRequestId]; if (waiter != null) { m_waitingForResponse.Remove(replyForRequestId); waiter.Response = messageStream; waiter.Notify(); } else { Debug.WriteLine("received not expected reply for request with id " + replyForRequestId); } } messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.LocateReply: // ignore, not interesting messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.CloseConnection: CloseConnection(); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; case GiopMsgTypes.CancelRequest: CdrInputStreamImpl input = new CdrInputStreamImpl(messageStream); GiopHeader cancelHeader = new GiopHeader(input); uint requestIdToCancel = input.ReadULong(); m_fragmentAssembler.CancelFragmentsIfInProgress(requestIdToCancel); messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.MessageError: CloseConnectionAfterUnexpectedException(new MARSHAL(16, CompletionStatus.Completed_MayBe)); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; default: // should not occur; // hint: fragment is also considered as error here, // because fragment should be handled before this loop // send message error SendErrorResponseMessage(); messageReceived.StartReceiveMessage(); // receive next message break; } }
/// <summary> /// abort receiving messages /// </summary> private void StopMessageReception() { lock(this) { m_messageReceiveTask = null; } }
/// <summary> /// begins receiving messages asynchronously /// </summary> internal void StartMessageReception() { lock(this) { if (m_messageReceiveTask == null) { m_messageReceiveTask = new MessageReceiveTask(m_transport, this); m_messageReceiveTask.StartReceiveMessage(); } // else ignore, already started } }
internal void ProcessLocateRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { // this called is completely handled by IIOP.NET // -> no servant will be called and therefore whole request is processed before reading next message try { m_receiver.ProcessLocateRequest(requestStream, m_serverCon); receiveTask.StartReceiveMessage(); } catch (Exception ex) { HandleUnexpectedProcessingException(); Trace.WriteLine("stopped processing on server connection after unexpected exception: " + ex); } }
internal void ProcessRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { // invariant: only one thread processing the first 3 statments at one instance in time // (statement nr 3 can lead to a next read allowing another i/o completion thread // to call this method) try { // call is serialised, no need for a lock; at most one thread is reading messages from transport. Interlocked.Increment(ref m_requestsInProgress); m_msgReceiveTask = receiveTask; m_receiver.ProcessRequest(requestStream, m_serverCon); // in the mean time, deserialise request notification may have been sent. // -> multiple requests are possible in progress and execute the following code int receivePending = Interlocked.Exchange(ref m_receivePending, NO_RECEIVE_PENDING); Interlocked.Decrement(ref m_requestsInProgress); // ReceivePending will be again set to true, when a request has been deserialised // and too many requests are processing if (receivePending == RECEIVE_PENDING) { // too many requests in parallel last time when trying to start receive // in NotifyDeserialiseRequestComplete -> do it now StartReadNextMessage(); } } catch (Exception ex) { HandleUnexpectedProcessingException(); Trace.WriteLine("stopped processing on server connection after unexpected exception: " + ex); } }
/// <summary> /// processes this locate reqeuest message /// </summary> private void ProcessLocateRequestMessage(Stream requestStream, MessageReceiveTask receiveTask) { lock(this) { if (m_reiceivedRequestDispatcher == null) { SendErrorResponseMessage(); // can't be handled, no dispatcher return; } } m_reiceivedRequestDispatcher.ProcessLocateRequestMessage(requestStream, receiveTask); }