Logo Search packages:      
Sourcecode: vdr-plugin-burn version File versions  Download package

manager.c

/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: manager.c,v 1.12 2006/09/16 18:33:36 lordjaxom Exp $
 */

#include "chain-vdr.h"
#include "manager.h"
#include "proctools/logger.h"
#include "proctools/format.h"
#include "proctools/functions.h"
#include <stdexcept>
#include <algorithm>
#include <vdr/skins.h>

namespace vdr_burn
{

      using namespace std;
      using proctools::logger;
      using proctools::process;
      using proctools::deleter;
      using proctools::format;

      manager::lock::lock():
            m_mutex(&manager::m_instance->m_mutex)
      {
            m_mutex->Lock();
      }

      manager::lock::~lock()
      {
            m_mutex->Unlock();
      }

      manager::manager():
                  cThread("burn-chain manager"),
                  m_pending( new job ),
                  m_active( 0 )
      {
            Start();
      }

      manager::~manager()
      {
            Cancel(10);
      }

      bool manager::get_is_busy()
      {
            lock man_lock;
            return m_instance->m_active != 0 || m_instance->m_queued.size() > 0;
      }

      void manager::start_pending()
      {
            lock man_lock;
            m_instance->m_queued.push_back(m_instance->m_pending.release());
            m_instance->m_pending.reset( new job );
            m_instance->m_condition.Broadcast();
      }

      void manager::replace_pending(job* job_)
      {
            lock man_lock;
            erase_job(job_);
            job_->reset();

            m_instance->m_pending.reset( job_ );
      }

      void manager::erase_job(job* job_)
      {
            job_queue::iterator item;
            if ((item = find(m_instance->m_queued.begin(),
                         m_instance->m_queued.end(), job_))
                        != m_instance->m_queued.end())
                  m_instance->m_queued.erase(item);
            else if ((item = find(m_instance->m_erroneous.begin(),
                                m_instance->m_erroneous.end(), job_))
                        != m_instance->m_erroneous.end())
                  m_instance->m_erroneous.erase(item);
            else if ((item = find(m_instance->m_canceled.begin(),
                                m_instance->m_canceled.end(), job_))
                        != m_instance->m_canceled.end())
                  m_instance->m_canceled.erase(item);
      }

      string manager::get_status_message()
      {
            lock myLock;

            if (m_instance->m_active != 0)
                  return format("{0} - {1}%") % (m_instance->m_queued.size() + 1) % m_instance->m_active->get_progress();
            return "";
      }

      void manager::start_if_idle()
      {
            if (m_active == 0 && m_queued.size() > 0) {
                  logger::debug("manager is starting first job");
                  m_active = m_queued.front();
                  m_queued.pop_front();
                  m_active->start();
            }
      }

      void manager::check_rotate()
      {
            if (m_active != 0 && !m_active->get_is_active()) {
                  logger::debug("manager picked up finished job, removing it");

                  // clear message queue
                  Skins.QueueMessage(mtInfo, 0, 0, 0);

                  if (m_active->get_is_canceled())
                        m_canceled.push_back(m_active);
                  else if (m_active->get_return_status() == process::error) {
                        m_erroneous.push_back(m_active);
                        Skins.QueueMessage(mtError, tr("A job failed!"), 10, 0);
                  }
                  else {
                        delete m_active;
                        Skins.QueueMessage(mtInfo, tr("A job was finished successfully."), 10, 0);
                  }
                  m_active = 0;
            }
      }

      bool manager::is_recording_queued( const std::string& filename )
      {
            manager::lock mlock;

            if ( ( m_instance->m_pending.get() != 0 && m_instance->m_pending->get_by_filename( filename ) != m_instance->m_pending->get_recordings().end() ) ||
                        ( m_instance->m_active != 0 && m_instance->m_active->get_by_filename( filename ) != m_instance->m_active->get_recordings().end() ) )
                  return true;

            for ( job_queue::iterator it = m_instance->m_queued.begin(); it != m_instance->m_queued.end(); ++it) {
                  if ( (*it)->get_by_filename( filename ) != (*it)->get_recordings().end() )
                        return true;
            }
            return false;
      }

      void manager::Action()
      {
            m_mutex.Lock();
            SetPriority(19);
            while (Running()) {
                  m_condition.TimedWait(m_mutex, 1000);

                  check_rotate();
                  start_if_idle();
            }

            delete m_active;
            for_each(m_queued.begin(), m_queued.end(), &deleter<job>);
            for_each(m_erroneous.begin(), m_erroneous.end(), &deleter<job>);
            for_each(m_canceled.begin(), m_canceled.end(), &deleter<job>);

            m_mutex.Unlock();
      }

}

Generated by  Doxygen 1.6.0   Back to index