MEL
Microthread & Execution library
mel::tasking::Runnable Class Reference

A class representing a "running" task, with added functionality to post events requesting execution of external code within it. More...

#include <Runnable.h>

Inheritance diagram for mel::tasking::Runnable:
mel::tasking::ThreadRunnable

Classes

struct  RunnableCreationOptions
 
struct  RunnableInfo
 

Public Member Functions

inline ::mel::core::ThreadId getOwnerThreadId () const
 
void setOwnerThreadId (mel::core::ThreadId tid)
 
void setDefaultFactory (ProcessFactory *factory)
 Change default factory used to create task through post and fireAndForget. More...
 
const ProcessFactorygetDefaultFactory () const
 Retrieves the current default factory for tasks.
 
void postTask (std::shared_ptr< Process > process, unsigned int startTime=0)
 
 Runnable (RunnableCreationOptions opts)
 Constructor.
 
template<bool ignoreNoThrow = false, class AllocatorType = ::mel::tasking::DefaultAllocator, class F , class KF = const std::function<bool()>&>
std::shared_ptr< Processpost (F &&task_proc, KF &&killFunction=killFalse, unsigned int period=0, unsigned int startTime=0)
 
template<bool ignoreNoThrow = false, class AllocatorType = ::mel::tasking::DefaultAllocator, class F , class KF = const std::function<bool()>&>
std::shared_ptr< ProcessfireAndForget (F &&task_proc, unsigned int startTime=0, KF &&killFunction=killTrue)
 Convenient function to post no periodic task with signature void f() More...
 
template<class TRet , class F , class KF = const std::function<bool()>&>
Future< TRet > execute (F &&function, KF &&killFunction=killFalse) noexcept
 Executes a function in a context of the Runnable. If this Runnable is in the same thread than caller then, depending on forcepost parameter, the functor will be executed directly (so Future<TRet> will be always available at return) or posted (so caller will need to wait on this Future or whatever other mechanism) More...
 
template<class TRet , class F , class KF = const std::function<bool()>&>
Future< TRet > execute (F &&function, Future< TRet >, KF &&killFunction=killFalse) noexcept
 Overload where output Future is given With this overload the given Future is fille with result from function. More...
 
const ProcessSchedulergetScheduler () const
 
ProcessSchedulergetScheduler ()
 
void setTimer (std::shared_ptr< Timer > timer)
 
const std::shared_ptr< TimergetTimer () const
 
std::shared_ptr< TimergetTimer ()
 
unsigned int getPendingTaskCount () const
 
unsigned int getActiveTaskCount () const
 
unsigned int getMaxPoolSize () const
 

Static Public Member Functions

static RunnablegetCurrentRunnable ()
 

Static Public Attributes

static const unsigned int DEFAULT_POOL_SIZE = 512
 
static std::function< bool()> killTrue
 helper function to automatically kill process when receiving kill signal
 
static std::function< bool()> killFalse
 helper function to reject kill when receiving kill signal
 

Protected Member Functions

void processTasks ()
 Performs a controlled loop over the internal queue, executing pending tasks. This function must be called always from same place, without altering the stack.
 
virtual void onPostTask (std::shared_ptr< Process > process)
 

Friends

class ::mel::tasking::_private::RunnableTask
 

Detailed Description

A class representing a "running" task, with added functionality to post events requesting execution of external code within it.

Any external thread can request any other runnable the execution of any piece of code through Runnable::post(...) methods.

The execution requests are internaly stored in a ProcessScheduler,and processed anytime after the call is made.

The first method simply blocks the calling thread until the requested task has been completed, or a timeout is reached. The second method just checks for task completion and returns inmediately.

For this scheme to work, subclasses must ensure that Runnable::processTasks(...) method is called often enough to satisfy the external execution requirements. Otherwise, an IllegalStateException maybe raised to calling threads when a new code execution is made and there is not enough room for the request.

Member Function Documentation

◆ execute() [1/2]

template<class TRet , class F , class KF >
Future< TRet > mel::tasking::Runnable::execute ( F &&  f,
Future< TRet >  output,
KF &&  killFunction = killFalse 
)
noexcept

Overload where output Future is given With this overload the given Future is fille with result from function.

Parameters
outputFuture where result must be put
Returns
same future as out

◆ execute() [2/2]

template<class TRet , class F , class KF >
Future< TRet > mel::tasking::Runnable::execute ( F &&  function,
KF &&  killFunction = killFalse 
)
noexcept

Executes a function in a context of the Runnable. If this Runnable is in the same thread than caller then, depending on forcepost parameter, the functor will be executed directly (so Future<TRet> will be always available at return) or posted (so caller will need to wait on this Future or whatever other mechanism)

Parameters
[in]functionFunctor with signature TRet f() that will be executed in this Runnable
[in]killFunction.Functor with signature bool () used when kill is executed while doing function.

◆ fireAndForget()

template<bool ignoreNoThrow, class AllocatorType , class F , class KF >
std::shared_ptr< Process > mel::tasking::Runnable::fireAndForget ( F &&  task_proc,
unsigned int  startTime = 0,
KF &&  killFunction = killTrue 
)

Convenient function to post no periodic task with signature void f()

see post for considerations con template parameter AllocatorType

Parameters
[in]task_procfunctor with signature void f(void)
[in]killFunction.Functor with signature bool () used when kill is executed while doing function.

◆ getScheduler()

const ProcessScheduler & mel::tasking::Runnable::getScheduler ( ) const
inline

Checks for a given task to be acomplished

Parameters
[in]taskIdthe task to check
Returns
true if the task has already been executed. false otherwise

◆ post()

template<bool ignoreNoThrow, class AllocatorType , class F , class KF >
std::shared_ptr< Process > mel::tasking::Runnable::post ( F &&  task_proc,
KF &&  killFunction = killFalse,
unsigned int  period = 0,
unsigned int  startTime = 0 
)

Posts a new execution request over a functor The execution is NOT guaranteed to be taken into account inmediatly. By default, a ::mel::tasking::_private::RunnableTask is created, which is intended to be used with a custom memory manager for performance reasons. Users can provide their own AllocatorType class to change the way the underlying Process is created, either by creating a custom specialization of GenericProcess or/and using a custom memory pool

See also
RTMemPool
Template Parameters
ignoreNoThrowIf false, an assertion is raised if callable task_proc is not noexcept. Default value = false
Parameters
[in]task_procthe functor to be executed. It has signature: bool (unsigned int msecs, Process*)
[in]killFunction.Functor with signature bool () used when kill is executed while doing function.
[in]periodMilliseconds
[in]startTimemilliseconds to begin task
Returns
the process created for this task

◆ postTask()

void mel::tasking::Runnable::postTask ( std::shared_ptr< Process process,
unsigned int  startTime = 0 
)

set callback to call when a task is added

Only one event, so you should get previous event to call chained (and free it)

Parameters
[in]functor.With signature void f(Runnable*,Process*)
Warning
not thread safe. Now it's only protected to allow only to children Posts new execution request. Adds the request to the queue and generates a new internal task id.
Parameters
[in]processstructure containing execution data.
Returns
an integer being the internal task id just created @internally, it calls protected onPostTask, so children can add custom behaviour

◆ setDefaultFactory()

void mel::tasking::Runnable::setDefaultFactory ( ProcessFactory factory)
inline

Change default factory used to create task through post and fireAndForget.

Warning
not multithread-safe. If tasks are being posted while this function is changed, it will reach to unpredictable results

◆ setOwnerThreadId()

void mel::tasking::Runnable::setOwnerThreadId ( mel::core::ThreadId  tid)
inline

Manually set the owner thread ID. Usually, the thread ID is automatically set when invoking ::run, but this allows the caller to set it up-front, just in case it's needed.

Parameters
tidthe owner thread to be set.

◆ setTimer()

void mel::tasking::Runnable::setTimer ( std::shared_ptr< Timer timer)

set timer to be used by internal scheduler If no Timer is given, a new Timer is created first time


The documentation for this class was generated from the following file: