Re: to const or not to const
"Alf P. Steinbach" <alfps@start.no> wrote in
news:hpm8cn$17p$1@news.eternal-september.org:
* Kai-Uwe Bux:
I recently dived into multi-threaded issues. To make my life a little
easier, I decided that it would be nice to have a simple fifo buffer
to ease communications between threads. The interface is this:
template < typename T >
class fifo {
public:
typedef T value_type;
typedef std::size_t size_type
fifo ( size_type n = -1 );
void push ( value_type const & value );
value_type pop ( void );
// blocks until an item is available
This method is very interesting. In a single-threaded program it
should clearly not be the basic interface but just a convenience
wrapper around 'top' and 'remove_top', because the copying of
value_type may throw after altering the fifo state, preventing sound
exception guarantee. But in a multi-threaded environment how does one
use the more primitive operations safely?
I can imagine that 'top' and 'remove_top' would be accessed within a
block protected by a mutex.
One way to have more exception safety is to use swap instead of copy.
After all, one wants to move the message away from the queue, not to copy
it. The swap operation can be often made no-throw quite easily.
My FIFO interface looks like:
template<class T, class WaitPolicy>
class ThreadFifo: private boost::noncopyable {
public:
ThreadFifo(const WaitPolicy& init_waiter);
void Post_mt(T& msg) {
// ... locking
fifo_.push_back(T());
fifo_.back().swap(msg);
// ..
}
void Fetch_mt(T& msg) {
// ... locking, waiting ...
msg.swap(fifo_.front());
fifo_.pop_front();
}
// ...
private:
typedef std::deque<T> fifo_t;
fifo_t fifo_;
};
The WaitPolicy template parameter decides if Fetch() is blocking or not.
If it is non-blocking or a timeout occured, a default-constructed message
is returned.
hth
Paavo