Public Member Functions | Protected Member Functions | Protected Attributes | Private Attributes

bea_VolumeReader Class Reference
[IVD Back-End Agent]

#include <bea_volumereader.h>

Inheritance diagram for bea_VolumeReader:
Inheritance graph
[legend]
Collaboration diagram for bea_VolumeReader:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 bea_VolumeReader (df_BlockManager &a_blkMgr, bea_Volume *const a_medVol_p, bool &a_fmDetected)
virtual ~bea_VolumeReader ()

Protected Member Functions

virtual void Run (void *a_arg)

Protected Attributes

df_MgrWriter m_mgrWriter
bea_Volume *const m_medVol_p
bool & m_fmDetected

Private Attributes

 log_CLASSID_m

Detailed Description

Definition at line 37 of file bea_volumereader.h.


Constructor & Destructor Documentation

bea_VolumeReader::bea_VolumeReader ( df_BlockManager a_blkMgr,
bea_Volume *const   a_medVol_p,
bool &  a_fmDetected 
)

Definition at line 46 of file bea_volumereader.cpp.

References log_FUNC_m.

    : m_mgrWriter(a_blkMgr),
      m_medVol_p(a_medVol_p),
      m_fmDetected(a_fmDetected) {

    log_FUNC_m(bea_VolumeReader);
}

bea_VolumeReader::~bea_VolumeReader (  )  [virtual]

Definition at line 57 of file bea_volumereader.cpp.

References log_FUNC_m.


Member Function Documentation

void bea_VolumeReader::Run ( void *  a_arg  )  [protected, virtual]

Reimplemented from cmn_Thread.

Definition at line 61 of file bea_volumereader.cpp.

References dbg_DETAIL, dbg_LOW, dbg_NORM, bea_Volume::DoMediumLogging(), df_MgrWriter::Flush(), bea_Medium::GetBarcode(), ivd_BaseException::GetContext(), ivd_BaseException::GetDetailed(), ivd_BaseException::GetError(), df_MgrWriter::GetFree(), df_DataBlock::GetFreeSize(), bea_Volume::GetJobID(), bea_Volume::GetMedium(), cmn_Time::GetMilliTime(), df_DataBlock::GetPosition(), bea_Volume::GetPosition(), cmn_Time::GetTime_t(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), ie_DATA_CORRUPTION, ie_MEDIUM_EOD, ie_MEDIUM_EOM, ie_MEDIUM_FILEMARK, ivd_Error, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_fmDetected, m_medVol_p, m_mgrWriter, df_DataBlock::Move(), NULL, bea_Volume::Read(), df_DataBlock::SetBlockID(), and df_MgrWriter::SetError().

                                      {
    log_FUNC_m(Run);

    log_DBG_m(dbg_LOW, "Medium reader thread started.");

    UInt32_t blocks(0);
    UInt64_t friSize(0);
    UInt32_t pos(m_medVol_p->GetPosition());
    const UInt32_t positionCheckInterval_c(10000);

    cmn_Time startTime;

    try {
        while(true) {
            df_DataBlock *blk = m_mgrWriter.GetFree();
            if (blk == NULL) {
                log_DBG_m(dbg_NORM, "Readers went down. Finish writing.");
                break;
            }

            UInt8_t     *buf    (blk->GetPosition());
            UInt32_t    bufSize (blk->GetFreeSize());
            
            if ( (pos % positionCheckInterval_c) == 0) {
                UInt32_t mediumPos(m_medVol_p->GetPosition());
                log_DBG_m(dbg_NORM,
                    "Verifying position. " <<
                    "Counted : " << pos <<
                    "Actual : "  << mediumPos);
                    
                if (pos != mediumPos) {
                    log_MARKLINE_m;
                    ostringstream sstr;
                    sstr
                        << "Counted medium position (" << pos << ")"
                        << " is different from actual (" << mediumPos << "). "
                        << "Job: " << m_medVol_p->GetJobID()
                        << "Medium/volume: "
                        << m_medVol_p->GetMedium()->GetBarcode() << "/"
                        << m_medVol_p->GetVolumeNumber();
                        
                    throw ivd_InternalError(ie_DATA_CORRUPTION, sstr.str());
                }
            }

            blk->SetBlockID(pos);
            log_DBG_m(dbg_DETAIL, "Medium read position: " << pos);
            try {
                // medium drive has block size already specified
                // and will read block_size bytes to the allocated buffer
                // BEA's block size MUST be the same as used here otherwise
                // it is a BUG.
                m_medVol_p->Read(buf);
                ++blocks, ++pos;
                friSize += bufSize;
                blk->Move(bufSize);
                m_mgrWriter.Flush();
            }
            catch (const ivd_Error &ie) {
                switch (ie.GetError()) {
                    case ie_MEDIUM_FILEMARK:
                        // File mark increases position.
                        m_fmDetected = true, ++pos;
                        log_DBG_m(dbg_LOW,
                            "File mark detected ==> stop reading data.");
                        goto STOP;
                        break;
                    case ie_MEDIUM_EOD:
                        log_DBG_m(dbg_LOW,
                            "End of data detected ==> stop reading data.");
                        goto STOP;
                        break;
                    case ie_MEDIUM_EOM:
                        log_DBG_m(dbg_LOW,
                            "Early end of medium detected ==> continue.");
                        break;

                    default:
                        log_DBG_m(dbg_LOW,
                        "Unknown exception while reading FRI ==> re-throw.");
                        m_mgrWriter.SetError(
                            new ivd_Error(
                                ie.GetError(), ie.GetContext(), ie.GetDetailed()) );
                        throw;
                }
            }
            catch (ivd_SysError &ie) {
                m_mgrWriter.SetError(
                    new ivd_SysError(
                        ie.GetError(), ie.GetContext(), ie.GetDetailed()) );
                throw;
            }
            catch (ivd_Exception &ie) {
                m_mgrWriter.SetError(
                    new ivd_Error(
                        ie.GetError(), ie.GetContext(), ie.GetDetailed()) );
                throw;
            }
        };
STOP:
        log_DBG_m(dbg_DETAIL, "End of reading the data.");
        
        if (pos % positionCheckInterval_c) {
            UInt32_t mediumPos(m_medVol_p->GetPosition());
            log_DBG_m(dbg_NORM,
                "Verifying position. " <<
                "Counted: " << pos <<
                "Actual: "  << mediumPos);
                
            if (pos != mediumPos) {
                log_MARKLINE_m;
                ostringstream sstr;
                sstr
                    << "Counted medium position (" << pos << ")"
                    << " is different from actual (" << mediumPos << "). "
                    << "Job: " << m_medVol_p->GetJobID()
                    << "Medium/volume: "
                    << m_medVol_p->GetMedium()->GetBarcode() << "/"
                    << m_medVol_p->GetVolumeNumber();
                    
                throw ivd_InternalError(ie_DATA_CORRUPTION, sstr.str());
            }
        }
    }
    catch (ivd_Error &ie) {
        log_DBG_m(dbg_LOW,
            "Problems reading from medium drive. Thread going down." << endl <<
            "Error: " << ie);
    }
    catch (ivd_BaseException &ie) {
        log_DBG_m(dbg_LOW,
            "Problems reading from medium drive. Thread going down." <<
            "Error: " << ie);
    }
    catch (std::exception &se) {
        log_DBG_m(dbg_LOW,
            "Problems reading from medium drive. Thread going down." <<
            "std::exception: " << se.what() );
    };

    cmn_Time endTime;
        cmn_Time diffTime = endTime - startTime;

    UInt64_t msecDiff =
            UInt64_t(diffTime.GetTime_t()) * 1000 +
            diffTime.GetMilliTime();

    if (msecDiff == 0) {
        msecDiff = 1;
    }

    UInt64_t speed = (friSize * 1000) / (msecDiff * 1024);

    if (m_medVol_p->DoMediumLogging()) {
        // log recreate FRI statistics
        ostringstream sstr;
        sstr
            << "Vol " << m_medVol_p->GetVolumeNumber()
            << ": FRI recreated for " << m_medVol_p->GetVolumeID()
            << " : " << friSize / 1024 << " KB (" << speed << " KB/s).";

        log_WriteEvent(
                sstr.str(), "",
                m_medVol_p->GetJobID(), 
                m_medVol_p->GetMedium()->GetBarcode());
    }

    log_DBG_m(dbg_LOW,
        "Read " << blocks << " blocks from medium.");

    log_DBG_m(dbg_LOW,"End of data.");
}

Here is the call graph for this function:


Member Data Documentation

Reimplemented from cmn_Thread.

Definition at line 56 of file bea_volumereader.h.

bool& bea_VolumeReader::m_fmDetected [protected]

Definition at line 51 of file bea_volumereader.h.

Referenced by Run().

Definition at line 50 of file bea_volumereader.h.

Referenced by Run().

Definition at line 49 of file bea_volumereader.h.

Referenced by Run().


The documentation for this class was generated from the following files: