示例#1
0
 internal void SendRequestMessageOneWay(Stream requestStream, uint requestId,
                                        GiopClientConnection connection)
 {
     SendMessage(requestStream);
     // no answer expected.
     connection.NotifyRequestSentCompleted();
 }
示例#2
0
        internal void SendRequestMessageAsync(Stream requestStream, uint requestId,
                                              AsyncResponseAvailableCallBack callback,
                                              IClientChannelSinkStack clientSinkStack,
                                              GiopClientConnection connection)
        {
            // interested in a response -> register to receive response.
            // this must be done before sending the message, because otherwise,
            // it would be possible, that a response arrives before being registered
            IResponseWaiter waiter;

            lock (m_waitingForResponse.SyncRoot) {
                // create and register wait handle
                waiter = new AsynchronousResponseWaiter(this, requestId, callback, clientSinkStack, connection,
                                                        m_timeout);
                if (!m_waitingForResponse.Contains(requestId))
                {
                    m_waitingForResponse[requestId] = waiter;
                }
                else
                {
                    throw new omg.org.CORBA.INTERNAL(40, CompletionStatus.Completed_No);
                }
            }
            SendMessage(requestStream);
            connection.NotifyRequestSentCompleted();
            // wait for completion or timeout
            waiter.StartWaiting(); // notify the waiter, that the time for the request starts; is non-blocking
        }
示例#3
0
        /// <summary>checks, if availabe connections contain one, which is usable. If yes, removes the connection
        /// from the available and returns it. </summary>
        /// <remarks>If unusable connections are found, closes and removes them from available and all connections.</remarks>
        /// <returns>the connection, if found, otherwise null.</returns>
        protected virtual GiopClientConnection GetFromAvailable(string connectionKey)
        {
            GiopClientConnection result = null;
            IList available             = (IList)m_availableConnections[connectionKey];

            while ((available != null) && (available.Count > 0))
            {
                GiopClientConnection con = (GiopClientConnection)available[available.Count - 1];
                available.RemoveAt(available.Count - 1);
                if (con.CanBeUsedForNextRequest())
                {
                    result = con;
                    break;
                }
                else
                {
                    try {
                        if (con.CanCloseConnection())
                        {
                            con.CloseConnection();
                        }
                    } catch (Exception) {
                    } finally {
                        UnregisterConnection(connectionKey, con);
                    }
                }
            }
            return(result);
        }
示例#4
0
        /// <summary>call back to call, when the async response has arrived.</summary>
        private void AsyncResponseArrived(IClientChannelSinkStack sinkStack, GiopClientConnection con,
                                          Stream responseStream, Exception resultException)
        {
            ITransportHeaders responseHeaders = new TransportHeaders();

            responseHeaders[GiopClientConnectionDesc.CLIENT_TR_HEADER_KEY] = con.Desc; // add to response headers

            // forward the response
            if ((resultException == null) && (responseStream != null))
            {
                #if DEBUG
                OutputHelper.LogStream(responseStream);
                #endif
                responseStream.Seek(0, SeekOrigin.Begin); // assure stream is read from beginning in formatter
                sinkStack.AsyncProcessResponse(responseHeaders, responseStream);
            }
            else
            {
                Exception toThrow = resultException;
                if (toThrow == null)
                {
                    toThrow = new omg.org.CORBA.INTERNAL(79, omg.org.CORBA.CompletionStatus.Completed_MayBe);
                }
                sinkStack.DispatchException(toThrow);
            }
        }
示例#5
0
 private void DestroyUnusedConnections(Object state)
 {
     lock (this) {
         bool hasDestroyedConnections = false;
         foreach (DictionaryEntry de in m_availableConnections)
         {
             IList list = (IList)de.Value;
             GiopClientConnection toDestroy = GetConToDestroy(list);
             if (toDestroy != null)
             {
                 list.Remove(toDestroy);
                 UnregisterConnection((string)de.Key, toDestroy);
                 try {
                     toDestroy.CloseConnection();
                 } catch (ThreadAbortException) {
                     throw;
                 } catch (Exception) {
                     // ignore
                 }
                 hasDestroyedConnections = true;
             }
         }
         if (hasDestroyedConnections)
         {
             Monitor.PulseAll(this); // inform all threads waiting on changes in connections
         }
     }
 }
示例#6
0
 internal GiopClientConnectionDesc(GiopClientConnectionManager conManager, GiopClientConnection connection,
                                   GiopRequestNumberGenerator reqNumberGen,
                                   GiopTransportMessageHandler transportHandler)
     : base(conManager, transportHandler)
 {
     m_reqNumGen  = reqNumberGen;
     m_connection = connection;
 }
示例#7
0
        /// <summary>
        /// Allocate a connection for the message to the given target.
        /// </summary>
        private GiopClientConnection AllocateConnectionForTarget(IMessage msg, IIorProfile target,
                                                                 string targetKey,
                                                                 out uint requestNr)
        {
            GiopClientConnection          result        = null;
            GiopClientInitiatedConnection newConnection = null; // contains the new connection, if one is created

            lock (this) {
                while (result == null)
                {
                    result = GetFromAvailable(targetKey);
                    if (result != null)
                    {
                        break;
                    }
                    else
                    {
                        // if no usable connection, create new one (if possible)
                        if (CanInitiateNewConnection(targetKey))
                        {
                            IClientTransport transport =
                                m_transportFactory.CreateTransport(target);
                            newConnection = CreateClientConnection(targetKey, transport, m_requestTimeOut);
                            result        = newConnection;
                        }
                        else
                        {
                            // wait for connections to become available
                            Monitor.Wait(this); // wait for a new connection to become available.
                        }
                    }
                }
                result.IncrementNumberOfRequests();
                requestNr = result.Desc.ReqNumberGen.GenerateRequestId();
                m_allocatedConnections[msg] = result;
                if (newConnection != null)
                {
                    // Register the new connection, if everything went ok
                    RegisterConnection(targetKey, result);
                }
            }
            if (newConnection != null)
            {
                // open the connection now outside the locked session,
                // to allow other threads to access connection manager during
                // this lenghty operation.
                try {
                    newConnection.OpenConnection();
                } catch (Exception) {
                    lock (this) {
                        // clean up dead connection
                        UnregisterConnection(targetKey, newConnection);
                    }
                    throw;
                }
            }
            return(result);
        }
示例#8
0
        /// <summary>
        /// unregister a connections among the list of all connections. Must be called only, when having
        /// the lock on the connection manager instance.
        /// </summary>
        protected virtual void UnregisterConnection(string targetKey, GiopClientConnection con)
        {
            IList connections = (IList)m_allClientConnections[targetKey];

            if (connections != null)
            {
                connections.Remove(con);
            }
        }
示例#9
0
        /// <summary>
        /// removes the connection from the available connections.
        /// </summary>
        protected void RemoveConnectionAvailable(string targetKey, GiopClientConnection con)
        {
            IList available = (IList)m_availableConnections[targetKey];

            if (available != null)
            {
                available.Remove(con);
            }
        }
示例#10
0
 internal AsynchronousResponseWaiter(GiopTransportMessageHandler transportHandler,
                                     uint requestId,
                                     AsyncResponseAvailableCallBack callback,
                                     IClientChannelSinkStack clientSinkStack,
                                     GiopClientConnection connection,
                                     MessageTimeout timeOut)
 {
     Initalize(transportHandler, requestId, callback, clientSinkStack, connection, timeOut);
 }
示例#11
0
        protected override void UnregisterConnection(string targetKey, GiopClientConnection con)
        {
            base.UnregisterConnection(targetKey, con);
            IList known = (IList)m_bidirConnections[targetKey];

            if (known != null)
            {
                known.Remove(con); // remove connection, if it's among bidir.
            }
        }
示例#12
0
        /// <summary>
        /// register a connections among the list of all connections. Must be called only, when having
        /// the lock on the connection manager instance.
        /// </summary>
        protected void RegisterConnection(string targetKey, GiopClientConnection con)
        {
            IList connections = (IList)m_allClientConnections[targetKey];

            if (connections == null)
            {
                connections = new ArrayList();
                m_allClientConnections[targetKey] = connections;
            }
            connections.Add(con);
        }
示例#13
0
 /// <summary>
 /// Notifies the connection manager, that a request has been completely sent on the connection.
 /// For non oneway messages, a reply is required before RequestOnConnectionCompleted is called.
 /// </summary>
 /// <remarks>if multiplexing is allowed, the connection can now be reused for a next request. This
 /// guarantuees, that the session based services like codeset work correctly.</remarks>
 internal void RequestOnConnectionSent(GiopClientConnection con)
 {
     if (m_allowMultiplex)
     {
         lock (this) {
             if (con.NumberOfRequestsOnConnection < m_maxNumberOfMultiplexedRequests)
             {
                 // if currently not too many requests on the same connection, register already
                 // as available.
                 SetConnectionAvailable(con.ConnectionKey, con);
             }
         }
     } // else: nothing to do, wait for request completion.
 }
示例#14
0
        /// <summary>
        /// sends the request and blocks the thread until the response message
        /// has arravied or a timeout has occured.
        /// </summary>
        /// <returns>the response stream</returns>
        internal Stream SendRequestSynchronous(Stream requestStream, uint requestId,
                                               GiopClientConnection connection)
        {
            // interested in a response -> register to receive response.
            // this must be done before sending the message, because otherwise,
            // it would be possible, that a response arrives before being registered
            IResponseWaiter waiter;

            lock (m_waitingForResponse.SyncRoot) {
                // create and register wait handle
                waiter = new SynchronousResponseWaiter(this);
                if (!m_waitingForResponse.Contains(requestId))
                {
                    m_waitingForResponse[requestId] = waiter;
                }
                else
                {
                    throw new omg.org.CORBA.INTERNAL(40, CompletionStatus.Completed_No);
                }
            }
            SendMessage(requestStream);
            connection.NotifyRequestSentCompleted();
            // wait for completion or timeout
            bool received = waiter.StartWaiting();

            waiter.Completed();
            if (received)
            {
                // get and return the message
                if (waiter.Problem != null)
                {
                    throw waiter.Problem;
                }
                else if (waiter.Response != null)
                {
                    return(waiter.Response);
                }
                else
                {
                    throw new INTERNAL(41, CompletionStatus.Completed_MayBe);
                }
            }
            else
            {
                CancelWaitForResponseMessage(requestId);
                CloseConnectionAfterTimeout();
                throw new omg.org.CORBA.TIMEOUT(31, CompletionStatus.Completed_MayBe);
            }
        }
示例#15
0
 private void Initalize(GiopTransportMessageHandler transportHandler,
                        uint requestId,
                        AsyncResponseAvailableCallBack callback,
                        IClientChannelSinkStack clientSinkStack,
                        GiopClientConnection connection,
                        MessageTimeout timeOutMillis)
 {
     m_alreadyNotified  = false;
     m_transportHandler = transportHandler;
     m_requestId        = requestId;
     m_callback         = callback;
     m_clientConnection = connection;
     m_clientSinkStack  = clientSinkStack;
     m_timeOut          = timeOutMillis;
 }
示例#16
0
        /// <summary>
        /// register the connection as available for a new request. Must be called only, when having
        /// the lock on the connection manager instance, i.e. in a block lock(this).
        /// </summary>
        protected void SetConnectionAvailable(string targetKey, GiopClientConnection con)
        {
            IList available = (IList)m_availableConnections[targetKey];

            if (available == null)
            {
                available = new ArrayList();
                m_availableConnections[targetKey] = available;
            }
            if (!available.Contains(con))   // possible, that this is called also if the connection is already available
            {
                available.Add(con);
                Monitor.Pulse(this); // inform the next object waiting on connections becoming available.
            }
        }
示例#17
0
        private GiopClientConnection GetClientConnection(IMessage msg)
        {
            GiopClientConnection con = m_conManager.GetConnectionFor(msg);

            if (con == null)
            {
                // should not occur, because AllocateConnectionFor has been previouse called
                throw new omg.org.CORBA.INTERNAL(998, omg.org.CORBA.CompletionStatus.Completed_No);
            }
            if (!con.CheckConnected())
            {
                // a new connection must not be opened, because this would require a remarshal
                // of the message (service-contexts) -> Therefore connection must already be open
                throw new omg.org.CORBA.TRANSIENT(CorbaSystemExceptionCodes.TRANSIENT_CONNECTION_DROPPED,
                                                  omg.org.CORBA.CompletionStatus.Completed_No, "Connection to target lost");
            }
            return(con);
        }
示例#18
0
 /// <summary>
 /// Notifies the connection manager, that the connection is no longer needed by the request, because
 /// the reply has been successfully received or an exception has occured.
 /// </summary>
 /// <remarks>if multiplexing is not allowed, the connection can now be reused for a next request.</remarks>
 internal void RequestOnConnectionCompleted(IMessage msg)
 {
     lock (this) {
         GiopClientConnection connection =
             (GiopClientConnection)m_allocatedConnections[msg];
         if (connection != null)
         {
             connection.UpdateLastUsedTime();
             connection.DecrementNumberOfRequests();
             // remove from allocated connections
             m_allocatedConnections.Remove(msg);
             // make sure, that connection is available again (must be called here in every case, because
             // RequestOnConnectionSent has not set it for sure also for mutex allowed).
             SetConnectionAvailable(connection.ConnectionKey, connection);
         }
         // else: nothing to do, because failed to register connection correctly
         // -> for simpler error handling, call this also, if something during allocation went wrong
     }
 }
示例#19
0
 public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream,
                            out ITransportHeaders responseHeaders, out Stream responseStream)
 {
     #if DEBUG
     OutputHelper.LogStream(requestStream);
     #endif
     // called by the chain, chain expect response-stream and headers back
     GiopClientConnection        clientCon = GetClientConnection(msg);
     GiopTransportMessageHandler handler   = clientCon.TransportHandler;
     // send request and wait for response
     responseHeaders = new TransportHeaders();
     responseHeaders[GiopClientConnectionDesc.CLIENT_TR_HEADER_KEY] = clientCon.Desc; // add to response headers
     uint reqNr = (uint)msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY];
     responseStream = handler.SendRequestSynchronous(requestStream, reqNr, clientCon);
     #if DEBUG
     OutputHelper.LogStream(responseStream);
     #endif
     responseStream.Seek(0, SeekOrigin.Begin); // assure stream is read from beginning in formatter
     // the previous sink in the chain does further process this response ...
 }
示例#20
0
 public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg,
                                 ITransportHeaders headers, Stream requestStream)
 {
     #if DEBUG
     OutputHelper.LogStream(requestStream);
     #endif
     // this is the last sink in the chain, therefore the call is not forwarded, instead the request is sent
     GiopClientConnection        clientCon = GetClientConnection(msg);
     GiopTransportMessageHandler handler   = clientCon.TransportHandler;
     uint reqNr = (uint)msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY];
     if (!GiopMessageHandler.IsOneWayCall((IMethodCallMessage)msg))
     {
         handler.SendRequestMessageAsync(requestStream, reqNr,
                                         new AsyncResponseAvailableCallBack(this.AsyncResponseArrived),
                                         sinkStack, clientCon);
     }
     else
     {
         handler.SendRequestMessageOneWay(requestStream, reqNr, clientCon);
     }
 }
 /// <summary>
 /// unregister a connections among the list of all connections. Must be called only, when having
 /// the lock on the connection manager instance.
 /// </summary>
 protected virtual void UnregisterConnection(string targetKey, GiopClientConnection con) {
     IList connections = (IList)m_allClientConnections[targetKey];
     if (connections != null) {
         connections.Remove(con);
     }
 }
示例#22
0
 internal AsynchronousResponseWaiter(GiopTransportMessageHandler transportHandler,
                                     uint requestId,
                                     AsyncResponseAvailableCallBack callback,
                                     IClientChannelSinkStack clientSinkStack,
                                     GiopClientConnection connection,
                                     MessageTimeout timeOut) {
     Initalize(transportHandler, requestId, callback, clientSinkStack, connection, timeOut);
 }
 /// <summary>
 /// removes the connection from the available connections.
 /// </summary>
 protected void RemoveConnectionAvailable(string targetKey, GiopClientConnection con) {
     IList available = (IList)m_availableConnections[targetKey];
     if (available != null) {
         available.Remove(con);
     }
 }
 /// <summary>
 /// register the connection as available for a new request. Must be called only, when having
 /// the lock on the connection manager instance, i.e. in a block lock(this).
 /// </summary>
 protected void SetConnectionAvailable(string targetKey, GiopClientConnection con) {
     IList available = (IList)m_availableConnections[targetKey];
     if (available == null) {
         available = new ArrayList();
         m_availableConnections[targetKey] = available;
     }
     if (!available.Contains(con)) { // possible, that this is called also if the connection is already available
         available.Add(con);
         Monitor.Pulse(this); // inform the next object waiting on connections becoming available.
     }
 }
示例#25
0
        /// <summary>call back to call, when the async response has arrived.</summary>
        private void AsyncResponseArrived(IClientChannelSinkStack sinkStack, GiopClientConnection con,
                                          Stream responseStream, Exception resultException) {
            ITransportHeaders responseHeaders = new TransportHeaders();
            responseHeaders[GiopClientConnectionDesc.CLIENT_TR_HEADER_KEY]= con.Desc; // add to response headers            

            // forward the response
            if ((resultException == null) && (responseStream != null)) {
                #if DEBUG
                OutputHelper.LogStream(responseStream);
                #endif                            
                responseStream.Seek(0, SeekOrigin.Begin); // assure stream is read from beginning in formatter
                sinkStack.AsyncProcessResponse(responseHeaders, responseStream);
            } else {
                Exception toThrow = resultException;
                if (toThrow == null) {
                    toThrow = new omg.org.CORBA.INTERNAL(79, omg.org.CORBA.CompletionStatus.Completed_MayBe);
                }
                sinkStack.DispatchException(toThrow);
            }                        
        }
 protected override void UnregisterConnection(string targetKey, GiopClientConnection con) {
     base.UnregisterConnection(targetKey, con);
     IList known = (IList)m_bidirConnections[targetKey];
     if (known != null) {
         known.Remove(con); // remove connection, if it's among bidir.
     }
 }
示例#27
0
 internal void SendRequestMessageAsync(Stream requestStream, uint requestId,
                                       AsyncResponseAvailableCallBack callback,
                                       IClientChannelSinkStack clientSinkStack,
                                       GiopClientConnection connection) {
     // interested in a response -> register to receive response.
     // this must be done before sending the message, because otherwise,
     // it would be possible, that a response arrives before being registered
     IResponseWaiter waiter;
     lock (m_waitingForResponse.SyncRoot) {
         // create and register wait handle
         waiter = new AsynchronousResponseWaiter(this, requestId, callback, clientSinkStack, connection,
                                                 m_timeout);
         if (!m_waitingForResponse.Contains(requestId)) {
             m_waitingForResponse[requestId] = waiter;
         } else {
             throw new omg.org.CORBA.INTERNAL(40, CompletionStatus.Completed_No);
         }
     }
     SendMessage(requestStream);
     connection.NotifyRequestSentCompleted();
     // wait for completion or timeout
     waiter.StartWaiting(); // notify the waiter, that the time for the request starts; is non-blocking
 }
示例#28
0
 internal void SendRequestMessageOneWay(Stream requestStream, uint requestId,
                                        GiopClientConnection connection) {
     SendMessage(requestStream);
     // no answer expected.
     connection.NotifyRequestSentCompleted();
 }
示例#29
0
 /// <summary>
 /// sends the request and blocks the thread until the response message
 /// has arravied or a timeout has occured.
 /// </summary>
 /// <returns>the response stream</returns>
 internal Stream SendRequestSynchronous(Stream requestStream, uint requestId,
                                        GiopClientConnection connection) {
     // interested in a response -> register to receive response.
     // this must be done before sending the message, because otherwise,
     // it would be possible, that a response arrives before being registered
     IResponseWaiter waiter;
     lock (m_waitingForResponse.SyncRoot) {
         // create and register wait handle
         waiter = new SynchronousResponseWaiter(this);
         if (!m_waitingForResponse.Contains(requestId)) {
             m_waitingForResponse[requestId] = waiter;
         } else {
             throw new omg.org.CORBA.INTERNAL(40, CompletionStatus.Completed_No);
         }
     }
     SendMessage(requestStream);
     connection.NotifyRequestSentCompleted();
     // wait for completion or timeout
     bool received = waiter.StartWaiting();
     waiter.Completed();
     if (received) {
         // get and return the message
         if (waiter.Problem != null) {
             throw waiter.Problem;
         } else if (waiter.Response != null) {
             return waiter.Response;
         } else {
             throw new INTERNAL(41, CompletionStatus.Completed_MayBe);
         }
     } else {
         CancelWaitForResponseMessage(requestId);
         CloseConnectionAfterTimeout();
         throw new omg.org.CORBA.TIMEOUT(31, CompletionStatus.Completed_MayBe);
     }
 }
 /// <summary>
 /// register a connections among the list of all connections. Must be called only, when having
 /// the lock on the connection manager instance.
 /// </summary>
 protected void RegisterConnection(string targetKey, GiopClientConnection con) {
     IList connections = (IList)m_allClientConnections[targetKey];
     if (connections == null) {
         connections = new ArrayList();
         m_allClientConnections[targetKey] = connections;
     }
     connections.Add(con);
 }
示例#31
0
 private void Initalize(GiopTransportMessageHandler transportHandler,
                        uint requestId,
                        AsyncResponseAvailableCallBack callback,
                        IClientChannelSinkStack clientSinkStack,
                        GiopClientConnection connection,
                        MessageTimeout timeOutMillis) {
     m_alreadyNotified = false;
     m_transportHandler = transportHandler;
     m_requestId = requestId;
     m_callback = callback;
     m_clientConnection = connection;
     m_clientSinkStack = clientSinkStack;
     m_timeOut = timeOutMillis;
 }
示例#32
0
 internal GiopClientConnectionDesc(GiopClientConnectionManager conManager, GiopClientConnection connection,
                                   GiopRequestNumberGenerator reqNumberGen,
                                   GiopTransportMessageHandler transportHandler)
     : base(conManager, transportHandler)
 {
     m_reqNumGen = reqNumberGen;
     m_connection = connection;
 }
 /// <summary>
 /// Notifies the connection manager, that a request has been completely sent on the connection.
 /// For non oneway messages, a reply is required before RequestOnConnectionCompleted is called.
 /// </summary>
 /// <remarks>if multiplexing is allowed, the connection can now be reused for a next request. This
 /// guarantuees, that the session based services like codeset work correctly.</remarks>
 internal void RequestOnConnectionSent(GiopClientConnection con) {
     if (m_allowMultiplex) {
         lock(this) {
             if (con.NumberOfRequestsOnConnection < m_maxNumberOfMultiplexedRequests) {
                 // if currently not too many requests on the same connection, register already
                 // as available.
                 SetConnectionAvailable(con.ConnectionKey, con);
             }
         }
     } // else: nothing to do, wait for request completion.
 }