//Editor-Info: -*- C++ -*-
//
//Subject: Scheduler Framework
//
//File: task.cpp
//
//Version: $Revision: 1.5 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/07/15 11:28:17 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      See corresponding header file
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 

#include "task.h"
#include "schedulerhandle.h"

//
// Methods: constructors
//
// Description:
//     Sets the default values of the class variables.
//

sfTask :: sfTask(void)
    : _handle(0),
      _priority(0),
      _load(0)
{
    return;
}


sfTask :: sfTask(const sfTask &other_)
    : _handle(0),
      _priority(other_._priority),
      _load(other_._load)
{
    return;
}


//
// Method: destructor
//
// Description:
//     If the task knows its scheduler, it is informed that this task
//     no longer exists and should be deleted from all scheduler queues.
//     It is now the responsibility of the scheduler not to call an
//     already deleted task.
//

sfTask :: ~sfTask(void)
{
    if (_handle != 0)
    {
        _handle->removeTask();
        delete _handle;
    }
    return;
}


const sfTask & sfTask :: operator = (const sfTask &other_)
{
    if (this != &other_) // Check for x = x
    {
        _priority = other_._priority;
        _load = other_._load;
    }
    return *this;
}
        

//
// Methods: Default event request methods
//
// Description:
//     These methods are provided to make it easier to request scheduled
//     events within task methods. They require that the task has a
//     handle to its scheduler; their usage is encouraged. (See callback
//     method and destructor comments.) In case there is no scheduler
//     handle set for this task, an exception is thrown.
//

void sfTask :: requestCPU(void)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->scheduleTask();
    return;
}

void sfTask :: requestTimeout(const OTime &timeout_)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->scheduleTimeout(timeout_);
    return;
}

void sfTask :: requestAbsoluteTimeout(const OTime &timeout_)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->scheduleAbsoluteTimeout(timeout_);
    return;
}

void sfTask :: requestRead(
    int fileDescriptor_,
    const OTime &timeout_)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->scheduleRead(fileDescriptor_, timeout_);
    return;
}

void sfTask :: requestWrite(
    int fileDescriptor_,
    const OTime &timeout_)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->scheduleWrite(fileDescriptor_, timeout_);
    return;
}


//
// Methods: Default event cancel methods
//
// Description:
//     Tell the scheduler (if exists) that an event requested by this
//     task should be cancelled. In case there is no scheduler handle
//     set for this task, an exception is thrown.
//

void sfTask :: cancelCPU(void)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->unscheduleTask();
    return;
}

void sfTask :: cancelTimeout(void)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
    }
    _handle->unscheduleTimeout();
    return;
}

void sfTask :: cancelRead(void)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
        _handle->unscheduleRead();
    }
    return;
}

void sfTask :: cancelWrite(void)
{
    if (_handle == 0)
    {
        sfException::throwInvalidRequestException();
        _handle->unscheduleWrite();
    }
    return;
}


//
// Methods: Default callback methods
//
// Description:
//     These are not pure virtual, so that some task implementation not
//     needing some of the callbacks doesn't have to implement all of
//     them. However, to help detect programming errors, all throw an
//     exception by default instead of being empty. If a task has
//     requested an event from the scheduler, it should actually do
//     something with it, right?
//

void sfTask :: runCallback(void)
{
    sfException::throwInvalidCallbackException();
    return;
}

void sfTask :: timeoutCallback(void)
{
    sfException::throwInvalidCallbackException();
    return;
}

void sfTask :: readCallback(void)
{
    sfException::throwInvalidCallbackException();
    return;
}

void sfTask :: writeCallback(void)
{
    sfException::throwInvalidCallbackException();
    return;
}


//
// Methods: get/set methods for the class variables
//
// Description:
//     Self-explanatory.
//

void sfTask :: setHandle(sfSchedulerHandle *handle_)
{
    _handle = handle_;
    return;
}

sfSchedulerHandle * sfTask :: getHandle(void) const
{
    return _handle;
}

void sfTask :: setPriority(int priority_)
{
    _priority = priority_;
    return;
}

int sfTask :: getPriority(void) const
{
    return _priority;
}

void sfTask :: setLoad(int load_)
{
    _load = load_;
    return;
}

int sfTask :: getLoad(void) const
{
    return _load;
}

