J
James Kanze
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
bool available ( void ) const;
// returns true if the a call to pop() would not block
void wait_available ( void ); // should this be const ?
// blocks until a call to pop() will not block
};
Typically there are some threads push()ing items into the fifo
and one thread pop()ing items off the buffer and processing
them.
If there's more than one thread popping, available and
wait_available are useless, of course.
In my own code, I've handled this by providing a timeout on pop:
if zero, it returns immediately, and if infinity, it behaves
effectively as your pop. But I've also had cases where it made
sense to wait at most 100 milliseconds, or such. (This solution
also avoids the const problem.)
It is clear that push() and pop() should not be const:
they change the contents of the buffer. Also, availble()
should be const since it just returns a property of the buffer
without modifying it.
But, what about wait_available()? Even though it does not
change the buffer contents by itself, once it returns it
effectively signals to the thread where it was called that
another thread has pushed in item. So it marks a change of the
buffer, even though it does not in itself bring that change
about. Should this method be const or not?
Does it change the (logical) contents of the buffer or not?
Practically speaking, however: is there the slightest reason to
worry about const on this class? Are there any real scenarios
where one might pass a const reference to it, or not have access
to the non-const instance for some reason?