Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

void Log_Writer::Run (  ) 

Starts the log writer.

The log writer is requesting log pages for output from the associated log queues. Log queues are served in a loop.

Definition at line 105 of file Log_Writer.cpp.

References Container_CircularList< T >::Anchor(), IOMan_Pages< PAGE >::Clear(), Container_Vector< T >::Clear(), Log_WriterTaskSynchronizer::DoSuspend(), EnableAddedLogDevice(), EnableAddedLogDeviceIsPossible(), EnoughPagesFreeForUserTaskWrite(), FreePagesForLogWriter(), Log_Queue::GetOutput(), IOMan_IKernelPages::GetPageCount(), Container_Vector< T >::GetSize(), Container_CircularList< T >::GetSize(), Log_WriterTaskSynchronizer::GetTaskID(), Container_Vector< T >::InsertEnd(), IOMan_IKernelPages::IsEmpty(), IOMan_IKernelPages::IsFull(), LOG_QUEUE_EMPTY, LOG_WRITER_NOT_INITIALIZED, LogVolume_Trace, m_Active, m_Allocated, m_IOSequenceNo, m_LogQueues, m_PagesFreeOnDevice, m_QueueRequests, m_RequestPages, m_SuspendedByUser, m_WriterTaskSync, PrepareAndFlushPageVector(), SetLogFullQueueState(), Log_WriterTaskSynchronizer::Suspend(), and WaitForUserResume().

{
    SAPDBTRACE_METHOD_DEBUG ("Log_Writer::Run", LogVolume_Trace, 5);
    
    m_Active = true;

    // ----------------------------------------------------------
    // check if writer has been initialized
    // ----------------------------------------------------------
    if (m_Allocated == false)
    {
        // writer not yet initialized:
        m_WriterTaskSync.Suspend(LOG_WRITER_NOT_INITIALIZED);
        // in the meantime, the writer might have been deactivated:
        if (m_Active == false)
            return;
        // writer may still not be initialized:
        if (m_Allocated == false)
            return;
    }

    // ----------------------------------------------------------
    // check for for added log volume to be activated
    // ----------------------------------------------------------
    if ( EnableAddedLogDeviceIsPossible() )
        EnableAddedLogDevice();

    // ----------------------------------------------------------
    // set start position for queue loop:
    // ----------------------------------------------------------
    QueueIterator        queueiter         = m_LogQueues.Anchor();
    m_PagesFreeOnDevice = FreePagesForLogWriter(); // PTS 1130059 mb 2004-06-09
    
    if ( EnoughPagesFreeForUserTaskWrite(m_PagesFreeOnDevice) )                   // PTS 1115488 mb 2002-05-03
    {
        // enable write for everybody into the Log_Queue
        SetLogFullQueueState(m_WriterTaskSync.GetTaskID(), false);
    }

    while (m_Active == true)
    {
        // ----------------------------------------------------------
        // check for log full and suspend if necessary
        // ----------------------------------------------------------
        while ( m_PagesFreeOnDevice == 0 )
        {
            RTE_Message(Log_Exception(__CONTEXT__,LOG_IS_FULL));
            
            m_WriterTaskSync.Suspend(LOG_DEVICE_FULL_SUSPEND);
            
            if (m_Active == false)
                return;
            
            m_PagesFreeOnDevice = FreePagesForLogWriter();
            
            if ( ! EnoughPagesFreeForUserTaskWrite(m_PagesFreeOnDevice) )                   // PTS 1115488 mb 2002-05-03
            {
                // only commit,rollback and savepoint are allowed due to log full
                SetLogFullQueueState(m_WriterTaskSync.GetTaskID(), true);
            }
        }

        // ----------------------------------------------------------
        // get pages for i/o:
        // ----------------------------------------------------------

        SAPDB_Bool firstflushedagain = false; // indicates whether last written page on device must be overwritten
        #ifdef SAPDB_SLOW
        if ( m_LogQueues.GetSize() > 1 )
            SAPDBERR_ASSERT_STATE(firstflushedagain == false);
        #endif

        QueueIterator fullloop = queueiter;
        
            m_RequestPages.Clear();
        m_QueueRequests.Clear();

        // ----------------------------------------------------------
        // loop associated log queues; accumulate log pages for i/o
        // ----------------------------------------------------------

        do   // PTS 1111918 mb 2001-09-27
        {
            Log_Queue& queue     = **queueiter;
            SAPDB_UInt pagecount = 0;
            
            queue.GetOutput (m_WriterTaskSync.GetTaskID(), 
                             m_PagesFreeOnDevice - m_RequestPages.GetPageCount(),
                             m_RequestPages,
                             pagecount,
                             firstflushedagain);
            
            if (pagecount > 0)
                m_QueueRequests.InsertEnd (QueueRequest(&queue,pagecount));

            ++queueiter;
        }
        while ( ! m_RequestPages.IsFull()
                &&
                (queueiter != fullloop)
                &&
                (m_PagesFreeOnDevice - m_RequestPages.GetPageCount() > 0) );
        
        // ----------------------------------------------------------
        // check whether there is output available:
        // ----------------------------------------------------------

        if (m_RequestPages.IsEmpty())
        {
            // no output available but free pages on the log
            m_WriterTaskSync.DoSuspend(LOG_QUEUE_EMPTY);
            // in the meantime, the writer might have been deactivated:
            if (m_Active == false)
                return;
        }
        else
        {
            Log_IOSequenceNo        ioseqnoBeforeFlush = m_IOSequenceNo;
            Log_RawDeviceIterator   firstWrittenPosition; // PTS 1125830 mb 2003-02-12

            // prepare and flush log pages:
            this->PrepareAndFlushPageVector(firstflushedagain, firstWrittenPosition);

            // remind queues that writer is ready:
            for (SAPDB_UInt i=0; i<m_QueueRequests.GetSize(); i++)
            {
                m_QueueRequests[i].pQueue->WriterTaskReady ( m_WriterTaskSync.GetTaskID(), 
                                                             ioseqnoBeforeFlush, 
                                                             firstWrittenPosition,
                                                             m_QueueRequests[i].pageCount );

                ioseqnoBeforeFlush   += m_QueueRequests[i].pageCount;
                firstWrittenPosition += m_QueueRequests[i].pageCount;
                m_PagesFreeOnDevice    -= m_QueueRequests[i].pageCount;
            }

            // ----------------------------------------------------------
            // check for for added log volume to be activated
            // ----------------------------------------------------------
    
            if ( EnableAddedLogDeviceIsPossible() )
            {
                EnableAddedLogDevice();
                m_PagesFreeOnDevice = FreePagesForLogWriter();
            }

            if ( ! EnoughPagesFreeForUserTaskWrite(m_PagesFreeOnDevice) )                   // PTS 1115488 mb 2002-05-03
            {
                m_PagesFreeOnDevice = FreePagesForLogWriter();
                if ( ! EnoughPagesFreeForUserTaskWrite(m_PagesFreeOnDevice) )                   // PTS 1115488 mb 2002-05-03
                {
                    // only commit,rollback and savepoint are allowed due to log full
                    SetLogFullQueueState(m_WriterTaskSync.GetTaskID(), true);
                }
            }
        }

        // ----------------------------------------------------------
        // check whether logwriter should be suspended by user
        // ----------------------------------------------------------
        if ( m_SuspendedByUser )
            WaitForUserResume();
            
    } // mainloop while (m_Active)
}


Generated by  Doxygen 1.6.0   Back to index