Archived

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

Best way to move data from a callback?

I have made a IceStorm application in C++ and MATLAB. The client callback gets the data, but I need the data in another thread, and I have thread safed a volatile global of the slice struct that is being transmitted. The problem seems to come from when the callback is held up when the other thread is outputing the data, and it causes a Ice::ConnectionLostException which I don't think I can catch because of it's context. What is the best way to move the data from the callback to the other thread? Do I even need to be thread safe with that object?

Comments

  • matthew
    matthew NL, Canada
    Please update your signature as required by our support policy as detailed in this thread http://www.zeroc.com/vbulletin/showthread.php?t=1697.

    I don't really understand what you are talking about, sorry. However, in general if you want to share data between threads you MUST protect it using some sort of mutual exclusion, such as a mutex. It sounds to me like what you really want to use is some sort of work queue between the callback (queues work) and the sender (in this case the worker thread). You can look at demo/IceUtil/workqueue for an example of how to write this.

    If this doesn't answer your question then you'll need to be more specific. Code is probably the best way to demonstrate the problem.
  • That should work, I'll try that.

    :edit:

    That indeed worked, and it works extremely well. Here is the object I used:
    #include <list>
    
    class NoItemOnQueueException : public Ice::Exception {};
    
    template<class T> class WorkQueue
    {
    public:
    	void add(const T& item)
    	{
    		IceUtil::Monitor<IceUtil::Mutex>::Lock lock(_monitor);
    		if(_queue.empty())
    		{
    			_monitor.notify();
    		}
    		_queue.push_back(item);
    	}
    
    	T nextItem()
    	{
    		IceUtil::Monitor<IceUtil::Mutex>::Lock lock(_monitor);
    		if(_queue.empty())
    			throw NoItemOnQueueException();
    
    		T item = _queue.front();
    		_queue.pop_front();
    		return item;
    	}
    private:
    	IceUtil::Monitor<IceUtil::Mutex> _monitor;
    	std::list<T> _queue;
    };
    

    My callback thread calls add, and my main thread calls items on the queue. I think this may stall when there is no more nextItems, but that shouldn't happen. But this was just the begining of Ice implimentation, so we will figure that one out when it happens. A timed wait should be able to break us out if there are no messages on the time step.

    :edit 2: I revised the code to handle when there is no data. Thanks a bunch, I can take it from here.