You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kget/slave.cpp

297 lines
7.7 KiB

/***************************************************************************
* slave.cpp
* -------------------
*
* Revision : $Id$
* begin : Tue Jan 29 2002
* copyright : (C) 2002 by Patrick Charbonnier
* : Based On Caitoo v.0.7.3 (c) 1998 - 2000, Matej Koss
* email : pch@freeshell.org
*
****************************************************************************/
/***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
***************************************************************************/
#include <tdeapplication.h>
#include "getfilejob.h"
#include "slave.h"
#include "slaveevent.h"
#include "transfer.h"
#include <assert.h>
Slave::Slave(Transfer * _parent, const KURL & _src, const KURL & _dest)
: TQObject(),
TQThread()
{
// FIXME
// KGet uses an unconventional threading model that relies on TDEIO slave execution from the main GUI thread
disableThreadPostedEvents(true);
mDebug << ">>>>Entering" << endl;
copyjob = NULL;
m_src = _src;
m_dest = _dest;
m_parent = _parent;
nPendingCommand = 0;
mDebug << ">>>>Leaving" << endl;
}
Slave::~Slave()
{}
void Slave::Op(SlaveCommand _cmd)
{
mDebugIn << " _cmd = " << _cmd << endl;
if ( !running() ) { // start on demand
start();
moveToThread(this);
}
mutex.lock();
stack.push(_cmd);
nPendingCommand++;
worker.wakeOne();
mutex.unlock();
mDebugOut << endl;
}
/** No descriptions */
void Slave::PostMessage(SlaveResult _event, TQ_ULLONG _data)
{
SlaveEvent *e1 = new SlaveEvent(m_parent, _event, _data);
TQApplication::postEvent(kapp->mainWidget(), (TQEvent *) e1);
}
void Slave::PostMessage(SlaveResult _event, const TQString & _msg)
{
SlaveEvent *e1 = new SlaveEvent(m_parent, _event, _msg);
TQApplication::postEvent(kapp->mainWidget(), (TQEvent *) e1);
mDebug << "Msg:" << "_msg = " << _msg << endl;
}
void Slave::InfoMessage(const TQString & _msg)
{
SlaveEvent *e1 = new SlaveEvent(m_parent, SLV_INFO, _msg);
TQApplication::postEvent(kapp->mainWidget(), (TQEvent *) e1);
mDebug << "Infor Msg:" << "_msg = " << _msg << endl;
}
void Slave::run()
{
mDebugIn << endl;
SlaveCommand cmd;
bool running = true;
while (running)
{
if (!nPendingCommand) {
worker.wait();
}
switch (cmd = fetch_cmd())
{
case RESTART:
// fall through
case RETR:
mDebug << " FETCHED COMMAND RETR" << endl;
PostMessage(SLV_RESUMED);
break;
case RETR_CACHE:
mDebug << " FETCHED COMMAND RETR_CACHE" << endl;
break;
case PAUSE:
mDebug << " FETCHED COMMAND PAUSE" << endl;
PostMessage(SLV_PAUSED);
break;
case KILL:
mDebug << " FETCHED COMMAND KILL" << endl;
running = false;
// no message posted
break;
case REMOVE:
mDebug << " FETCHED COMMAND REMOVE" << endl;
running = false;
PostMessage(SLV_REMOVED);
break;
case SCHEDULE:
mDebug << " FETCHED COMMAND SCHEDULE" << endl;
PostMessage(SLV_SCHEDULED);
break;
case DELAY:
mDebug << " FETCHED COMMAND DELAY" << endl;
PostMessage(SLV_DELAYED);
break;
case NOOP:
mDebug << "FETCHED COMMAND NOOP, i.e. empty stack" << endl;
running = false;
break;
default:
mDebug << " UNKNOWN COMMAND DIE...." << endl;
assert(0);
}
}
assert(!copyjob);
mDebugOut << endl;
}
Slave::SlaveCommand Slave::fetch_cmd()
{
mutex.lock();
SlaveCommand cmd = NOOP;
if ( !stack.isEmpty() )
{
nPendingCommand--;
cmd = stack.pop();
}
mutex.unlock();
return cmd;
}
void Slave::Connect()
{
mDebugIn << endl;
connect(copyjob, TQ_SIGNAL(canceled(TDEIO::Job *)), TQ_SLOT(slotCanceled(TDEIO::Job *)));
connect(copyjob, TQ_SIGNAL(connected(TDEIO::Job *)), TQ_SLOT(slotConnected(TDEIO::Job *)));
connect(copyjob, TQ_SIGNAL(result(TDEIO::Job *)), TQ_SLOT(slotResult(TDEIO::Job *)));
connect(copyjob, TQ_SIGNAL(totalSize(TDEIO::Job *, TDEIO::filesize_t)), TQ_SLOT(slotTotalSize(TDEIO::Job *, TDEIO::filesize_t)));
connect(copyjob, TQ_SIGNAL(processedSize(TDEIO::Job *, TDEIO::filesize_t)), TQ_SLOT(slotProcessedSize(TDEIO::Job *, TDEIO::filesize_t)));
connect(copyjob, TQ_SIGNAL(speed(TDEIO::Job *, unsigned long)), TQ_SLOT(slotSpeed(TDEIO::Job *, unsigned long)));
connect(copyjob, TQ_SIGNAL(infoMessage(TDEIO::Job *, const TQString &)), TQ_SLOT(slotInfoMessage(TDEIO::Job *, const TQString &)));
mDebugOut << endl;
}
void Slave::slotCanceled(TDEIO::Job *)
{
mDebugIn << endl;
mDebugOut << endl;
}
void Slave::slotConnected(TDEIO::Job *)
{
mDebugIn << endl;
mDebugOut << endl;
}
void Slave::slotResult(TDEIO::Job * job)
{
mDebugIn << endl;
assert(copyjob == job);
copyjob=0L;
TDEIO::Error error=TDEIO::Error(job->error());
if (!error) {
PostMessage(SLV_FINISHED);
}
else {
if (m_parent->getMode() == Transfer::MD_NEW)
{
PostMessage(SLV_NOTINCACHE);
return;
}
TQString tmsg="<font color=\"red\"> <b>" + job->errorString() + \
"</b></font>";
InfoMessage(tmsg);
if (m_parent->retryOnError() && \
((error==TDEIO::ERR_COULD_NOT_LOGIN) || (error==TDEIO::ERR_SERVER_TIMEOUT))) {
//Timeout or login error
PostMessage(SLV_ERROR);
}
else if (m_parent->retryOnBroken() && (error==TDEIO::ERR_CONNECTION_BROKEN)) {
// Connection Broken
PostMessage(SLV_BROKEN);
}
else {
job->showErrorDialog();
PostMessage(SLV_DELAYED);
}
}
mDebugOut << endl;
}
void Slave::slotSpeed(TDEIO::Job *, unsigned long lSpeed)
{
// mDebugIn<<endl;
PostMessage(SLV_PROGRESS_SPEED, lSpeed);
// mDebugOut<<endl;
}
void Slave::slotTotalSize(TDEIO::Job *, TDEIO::filesize_t _total_size)
{
mDebugIn << "= " << _total_size << endl;
if ((int)_total_size == 0)//shouldn't happen, but does
return;
if (m_parent->getMode() != Transfer::MD_NEW)
{
PostMessage(SLV_CAN_RESUME, copyjob->getCanResume());
PostMessage(SLV_CONNECTED);
}
else
InfoMessage("checking if file is in cache...yes");
PostMessage(SLV_TOTAL_SIZE, _total_size);
mDebugOut << endl;
}
void Slave::slotProcessedSize(TDEIO::Job *, TDEIO::filesize_t _processed_size)
{
// mDebugIn<<endl;
PostMessage(SLV_PROGRESS_SIZE, _processed_size);
// mDebugOut<<endl;
}
void Slave::slotInfoMessage(TDEIO::Job *, const TQString & _msg)
{
mDebugIn << "MSG=" << _msg << endl;
InfoMessage(_msg);
mDebugOut << endl;
}
#include "slave.moc"