/* * 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 #include #include 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); for_each(m_erroneous.begin(), m_erroneous.end(), &deleter); for_each(m_canceled.begin(), m_canceled.end(), &deleter); m_mutex.Unlock(); } }