void RcfSession::processOobMessages()
    {
        if (mRequest.mOutOfBandRequest.getLength() > 0)
        {

            ThreadInfoPtr threadInfoPtr = getTlsThreadInfoPtr();
            if (threadInfoPtr)
            {
                threadInfoPtr->notifyBusy();
            }

            OobMessagePtr msgPtr = OobMessage::decodeRequestCommon(
                mRequest.mOutOfBandRequest);

            switch ( msgPtr->getMessageType() )
            {
            case Omt_RequestTransportFilters:
                {
                    OobRequestTransportFilters & rtfMsg = 
                        static_cast<OobRequestTransportFilters &>(*msgPtr);


#if RCF_FEATURE_SERVER==1
                    rtfMsg.mResponseError = 
                        mRcfServer.mFilterServicePtr->RequestTransportFilters(
                        rtfMsg.mFilterIds);
#else
                    Exception e(_RcfError_NotSupportedInThisBuild("Transport filters"));
                    rtfMsg.mResponseError = e.getErrorId();
                    rtfMsg.mResponseErrorString = e.getErrorString();
#endif

                }
                break;

            case Omt_CreateCallbackConnection:
                {
                    OobCreateCallbackConnection & rtfMsg = 
                        static_cast<OobCreateCallbackConnection &>(*msgPtr);

#if RCF_FEATURE_SERVER==1
                    mRcfServer.mCallbackConnectionServicePtr->CreateCallbackConnection();
                    rtfMsg.mResponseError = RcfError_Ok;
#else
                    Exception e(_RcfError_NotSupportedInThisBuild("Callback connections"));
                    rtfMsg.mResponseError = e.getErrorId();
                    rtfMsg.mResponseErrorString = e.getErrorString();
#endif
                }
                break;

            case Omt_RequestSubscription:
                {
                    OobRequestSubscription & rtfMsg = 
                        static_cast<OobRequestSubscription &>(*msgPtr);

#if RCF_FEATURE_PUBSUB==1
                    rtfMsg.mResponseError = mRcfServer.mPublishingServicePtr->RequestSubscription(
                        rtfMsg.mPublisherName, 
                        rtfMsg.mSubToPubPingIntervalMs, 
                        rtfMsg.mPubToSubPingIntervalMs);
#else
                    Exception e(_RcfError_NotSupportedInThisBuild("Subscriptions"));
                    rtfMsg.mResponseError = e.getErrorId();
                    rtfMsg.mResponseErrorString = e.getErrorString();
#endif
                }
                break;

            default:

                RCF_THROW( Exception(_RcfError_Decoding()) );
            }

            ByteBuffer buffer;
            msgPtr->encodeResponse(buffer);
            mRequest.mOutOfBandResponse = buffer;
        }
        else
        {
            mRequest.mOutOfBandResponse = ByteBuffer();
        }
    }
    void RcfSession::invokeServant()
    {
        StubEntryPtr stubEntryPtr = mRequest.locateStubEntryPtr(mRcfServer);

        if (    NULL == stubEntryPtr.get() 
            &&  mRequest.getFnId() != -1)
        {
            Exception e( _RcfError_NoServerStub(
                mRequest.getService(), 
                mRequest.getSubInterface(),
                mRequest.getFnId()));

            RCF_THROW(e)(mRequest.getFnId());
        }
        else
        {
            setCachedStubEntryPtr(stubEntryPtr);

            SessionTouch sessionTouch(*this);

            StubEntryTouch stubEntryTouch(stubEntryPtr);

            if (!mTransportProtocolVerified)
            {
                bool bypassTransportProtocolCheck = 
                        (mRequest.getService() == "I_RequestTransportFilters")
                    ||  mRequest.mFnId == -1;

                bool doTransportProtocolCheck = ! bypassTransportProtocolCheck;

                if (doTransportProtocolCheck)
                {
                    verifyTransportProtocol(mTransportProtocol);
                    mTransportProtocolVerified = true;
                }
            }

            processOobMessages();

            if (mRequest.getFnId() == -1)
            {
                // Function id -1 is a canned ping request. Set a timestamp 
                // on the current session and return immediately.

                AllocateServerParameters<Void>()(*this);
                setPingTimestamp();
            }
            else
            {
                registerForPingBacks();

                ThreadInfoPtr threadInfoPtr = getTlsThreadInfoPtr();
                if (threadInfoPtr)
                {
                    threadInfoPtr->notifyBusy();
                }

                stubEntryPtr->getRcfClientPtr()->getServerStub().invoke(
                    mRequest.getSubInterface(),
                    mRequest.getFnId(),
                    *this);
            }
        }
    }
Beispiel #3
0
    void RcfSession::processRequest()
    {
        MethodInvocationRequest &request = mRequest;

        CurrentRcfSessionSentry guard(*this);

        StubEntryPtr stubEntryPtr = request.locateStubEntryPtr(mRcfServer);

        // NB: the following scopeguard is apparently not triggered by 
        // Borland C++, when throwing non std::exception derived exceptions.

        using namespace boost::multi_index::detail;

        scope_guard sendResponseUncaughtExceptionGuard =
            make_obj_guard(
                *this,
                &RcfSession::sendResponseUncaughtException);

        try
        {
            mAutoSend = true;

            if (NULL == stubEntryPtr.get() && request.getFnId() != -1)
            {
                Exception e( _RcfError_NoServerStub(
                    request.getService(), 
                    request.getSubInterface(),
                    request.getFnId()));

                RCF_THROW(e)(request.getFnId());
            }
            else
            {
                setCachedStubEntryPtr(stubEntryPtr);

                SessionTouch sessionTouch(*this);

                StubEntryTouch stubEntryTouch(stubEntryPtr);

                if (request.getFnId() == -1)
                {
                    // Function id -1 is a canned ping request. We set a
                    // timestamp on the current session and return immediately.

                    AllocateServerParameters<Void>()(*this);

                    setPingTimestamp();
                }
                else
                {
                    registerForPingBacks();

                    ThreadInfoPtr threadInfoPtr = getThreadInfoPtr();
                    if (threadInfoPtr)
                    {
                        threadInfoPtr->notifyBusy();
                    }

                    stubEntryPtr->getRcfClientPtr()->getServerStub().invoke(
                        request.getSubInterface(),
                        request.getFnId(),
                        *this);
                }
                
                sendResponseUncaughtExceptionGuard.dismiss();
                if (mAutoSend && !mRequest.mOneway)
                {
                    sendResponse();
                }
                else if (mRequest.mOneway)
                {
                    RCF_ASSERT(mAutoSend);
                    RCF_LOG_3()(this) << "RcfServer - suppressing response to oneway call.";
                    mIn.clearByteBuffer();
                    clearParameters();
                    setCurrentRcfSessionPtr();
                    onWriteCompleted();
                }
            }
        }
        catch(const std::exception &e)
        {
            sendResponseUncaughtExceptionGuard.dismiss();
            if (mAutoSend && !mRequest.mOneway)
            {
                sendResponseException(e);
            }
            else
            {
                mIn.clearByteBuffer();
                clearParameters();
                setCurrentRcfSessionPtr();
                onWriteCompleted();
            }
        }
    }