/// <summary>abort all requests, which wait for a reply</summary> private void AbortAllPendingRequestsWaiting() { try { lock (m_waitingForResponse.SyncRoot) { foreach (DictionaryEntry entry in m_waitingForResponse) { try { IResponseWaiter waiter = (IResponseWaiter)entry.Value; waiter.Problem = new omg.org.CORBA.COMM_FAILURE( CorbaSystemExceptionCodes.COMM_FAILURE_CONNECTION_DROPPED, CompletionStatus.Completed_MayBe); waiter.Notify(); } catch (Exception ex) { Debug.WriteLine("exception while aborting message: " + ex); } } m_waitingForResponse.Clear(); } } catch (Exception) { // ignore } }
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; } }