Base::Base():
mode(M_READ),
- eof_flag(false)
+ eof_flag(false),
+ mutex(0)
{ }
Base::~Base()
{
signal_deleted.emit();
+ delete mutex;
}
void Base::check_access(Mode m) const
throw logic_error("Base::get_handle");
}
+
+Base::Synchronize::Synchronize(Base &i):
+ io(i)
+{
+ if(!io.mutex)
+ io.mutex = new Mutex;
+ io.mutex->lock();
+}
+
+Base::Synchronize::~Synchronize()
+{
+ io.mutex->unlock();
+}
+
} // namespace IO
} // namespace Msp
#define MSP_IO_BASE_H_
#include <sigc++/sigc++.h>
+#include <msp/core/mutex.h>
#include "handle.h"
#include "mode.h"
#include "poll.h"
class Base
{
public:
+ /** RAII synchronization primitive. Prevents concurrent access to the
+ target object during the lifetime of the Synchronize object. */
+ class Synchronize
+ {
+ private:
+ Base &io;
+
+ public:
+ Synchronize(Base &);
+ ~Synchronize();
+ };
+
/** Emitted when there is no more data to be read. */
sigc::signal<void> signal_end_of_file;
protected:
Mode mode;
bool eof_flag;
+ Mutex *mutex;
Base();
private:
if(s<0 || l<0)
throw invalid_argument("Slice");
+ Base::Synchronize sync(below);
mode = below.get_mode()&M_RDWR;
below.signal_flush_required.connect(sigc::mem_fun(this, &Slice::flush));
}
check_access(m);
if(sync_position)
- seek(position, S_BEG);
+ {
+ SeekOffset pos = below.seek(start_offset+position, S_BEG)-start_offset;
+ if(pos!=position)
+ throw runtime_error("failed to restore position");
+ sync_position = false;
+ }
SeekOffset remaining = start_offset+length-position;
if(size>remaining)
unsigned Slice::do_write(const char *data, unsigned size)
{
+ Base::Synchronize sync(below);
size = prepare_op(size, M_WRITE);
if(!size)
return 0;
unsigned Slice::do_read(char *data, unsigned size)
{
+ Base::Synchronize sync(below);
size = prepare_op(size, M_READ);
if(!size)
return 0;
unsigned Slice::put(char c)
{
+ Base::Synchronize sync(below);
if(!prepare_op(1, M_WRITE))
return 0;
int Slice::get()
{
+ Base::Synchronize sync(below);
if(!prepare_op(1, M_READ))
return 0;
SeekOffset Slice::seek(SeekOffset off, SeekType type)
{
+ Base::Synchronize sync(below);
off += start_offset;
if(type==S_CUR)
off += position;