Archived

This forum has been archived. Please start a new discussion on GitHub.

when is an AMI callback finished?

Greetings!
Assume you need to get a value that is returned from an AMI via ice_response, but outside of ice_response (because the AMI_class_methodI class is instantiated somewhere else).
When implementing the 'callback class' (ice_response method) for an AMI, how can you tell from the outside whether the ice_response has arrived? The documentation has a footnote to Section 17.2.1 that states that polling is not supported but could be implemented easily by the application.
Our guess would be to use some sort of flag, set this flag at the end of ice_response and the method that is interested in the return (response) value would poll this flag.
Is there an easier way to do this?

Ingmar

Comments

  • marc
    marc Florida
    Either you can do whatever action needs to be taken directly in the AMI callback, which is the most efficient way to work with asynchronous method invocations, or with callbacks in general; or you can set a flag and check this flag as you suggest.

    For the latter, the code could look like this (in C++):
    class CallbackBase : public IceUtil::Monitor<IceUtil::Mutex>
    {
    public:
    
        CallbackBase() :
    	_called(false)
        {
        }
    
        void waitUntilCalled()
        {
    	IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
    	while(!_called)
    	{
    	    wait();
    	}
        }
    
        void checkIfCalled()
        {
    	IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
    	return _called;
        }
    
    protected:
    
        void called()
        {
    	IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
    	_called = true;
    	notify();
        }
    
    private:
    
        bool _called;
    };
    
    class AMI_class_methodI : public AMI_class_method, public CallbackBase
    {
    public:
    
        virtual void ice_response()
        {
            // Set some other flags...
    	called();
        }
    
        virtual void ice_exception(const ::Ice::Exception&)
        {
            // Set some other flags...
    	called();
        }
    };
    
    typedef IceUtil::Handle<AMI_class_methodI> AMI_class_methodIPtr;
    

    For an example, have a look at test/Ice/operations/TwowaysAMI.cpp.