FailoverDataIO.h

00001 /* This file is Copyright 2000-2008 Meyer Sound Laboratories Inc.  See the included LICENSE.txt file for details. */
00002 
00003 #ifndef MuscleFailoverDataIO_h
00004 #define MuscleFailoverDataIO_h
00005 
00006 #include "dataio/DataIO.h"
00007 #include "util/Queue.h"
00008 
00009 BEGIN_NAMESPACE(muscle);
00010  
00011 class FailoverDataIO;
00012 
00014 class IFailoverNotifyTarget
00015 {
00016 public:
00018    IFailoverNotifyTarget() {/* empty */}
00019 
00021    virtual ~IFailoverNotifyTarget() {/* empty */}
00022 
00026    virtual void DataIOFailover(const FailoverDataIO & source) = 0;
00027 };
00028 
00034 class FailoverDataIO : public DataIO
00035 {
00036 public:
00042    FailoverDataIO(int logErrorLevel = MUSCLE_LOG_NONE) : _logErrorLevel(logErrorLevel), _target(NULL) {/* empty */}
00043 
00045    virtual ~FailoverDataIO() {/* empty */}
00046 
00047    virtual int32 Read(void * buffer, uint32 size)
00048    {
00049       while(HasChild())
00050       {
00051          int32 ret = GetChild()->Read(buffer, size);
00052          if (ret >= 0) return ret;
00053                   else Failover();
00054       }
00055       return -1;
00056    }
00057 
00058    virtual int32 Write(const void * buffer, uint32 size) 
00059    {
00060       while(HasChild())
00061       {
00062          int32 ret = GetChild()->Write(buffer, size);
00063          if (ret >= 0) return ret;
00064                   else Failover();
00065       }
00066       return -1;
00067    }
00068 
00069    virtual status_t Seek(int64 offset, int whence)
00070    {
00071       while(HasChild())
00072       {
00073          status_t ret = GetChild()->Seek(offset, whence);
00074          if (ret == B_NO_ERROR) return ret;
00075                            else Failover();
00076       }
00077       return B_ERROR;
00078    }
00079 
00080    virtual int64 GetPosition() const {return HasChild() ? GetChild()->GetPosition() : -1;}
00081 
00082    virtual uint64 GetOutputStallLimit() const {return HasChild() ? GetChild()->GetOutputStallLimit() : MUSCLE_TIME_NEVER;}
00083 
00084    virtual void FlushOutput() {if (HasChild()) GetChild()->FlushOutput();}
00085 
00086    virtual void Shutdown() {_childIOs.Clear();}
00087 
00088    virtual const SocketRef & GetSelectSocket() const {return (HasChild()) ? GetChild()->GetSelectSocket() : GetNullSocket();}
00089 
00090    virtual status_t GetReadByteTimeStamp(int32 whichByte, uint64 & retStamp) const {return HasChild() ? GetChild()->GetReadByteTimeStamp(whichByte, retStamp) : B_ERROR;}
00091 
00092    virtual bool HasBufferedOutput() const {return HasChild() ? GetChild()->HasBufferedOutput() : false;}
00093 
00094    virtual void WriteBufferedOutput() {if (HasChild()) GetChild()->WriteBufferedOutput();}
00095 
00097    const Queue<DataIORef> & GetChildDataIOs() const {return _childIOs;}
00098 
00100    Queue<DataIORef> & GetChildDataIOs() {return _childIOs;}
00101 
00107    virtual void Failover() 
00108    {
00109       (void) _childIOs.RemoveHead();
00110       if (HasChild()) LogTime(_logErrorLevel, "FailoverDataIO:  Child IO errored out, failing over to next child ("UINT32_FORMAT_SPEC" children left)!\n", _childIOs.GetNumItems());
00111                  else LogTime(_logErrorLevel, "FailoverDataIO:  Child IO errored out, no backup children left!\n");
00112       if (_target) _target->DataIOFailover(*this);
00113    }
00114    
00116    void SetFailoverNotifyTarget(IFailoverNotifyTarget * t) {_target = t;}
00117 
00119    IFailoverNotifyTarget * GetFailoverNotifyTarget() const {return _target;}
00120 
00121 private:
00122    bool HasChild() const {return (_childIOs.HasItems());}
00123    DataIO * GetChild() const {return (_childIOs.Head()());}
00124 
00125    Queue<DataIORef> _childIOs;
00126    int _logErrorLevel;
00127    IFailoverNotifyTarget * _target;
00128 };
00129 
00130 END_NAMESPACE(muscle);
00131 
00132 #endif

Generated on Thu Jun 5 17:47:53 2008 for MUSCLE by  doxygen 1.5.1