JobInterface Class Reference

#include <job.h>

Inheritance diagram for JobInterface:

Detailed Description

A job is a threaded entity that can be enqueued or added to a group. A JobRef is similar to a ThreadRef but all jobs on the same queue (JobQueueRef) share a set of worker threads whereas each ThreadRef has its own private thread.

Once a job has been enqueued it will be executed as soon as a worker thread of the specified queue is available. In general jobs must be independent of each other. The order and timing of the execution as well as the chosen worker thread are completely up to the job system. It keeps the worker threads as busy as possible until a queue is (temporarily) empty.

One way to create a job is to inherit from JobInterface/JobInterfaceTemplate and to implement operator (), for example

class MyJob : public JobInterfaceTemplate<MyJob>
{
public:
Result<void> operator ()()
{
... your code goes here ...
}
};

A job is reference counted. A typical application might involve creating a job with Create() (or NewObj) and enqueueing it. Your job will automatically be deleted once it is not referenced anymore. The same applies to jobs that are added to a group.

Instead of creating an object that is derived from JobInterface you may also enqueue a lambda expression which can have the advantage of writing code that is easier to manage because the parallelized tasks appear in sequential order in the source code.

if (doSomethingThatTakesAWhile)
{
[]()
{
... your parallel code goes here ...
}
JobRef & Enqueue(JobQueueInterface *queue=JOBQUEUE_CURRENT)
Definition: job.h:1342
#define iferr_return
Definition: resultbase.h:1519

Jobs are not allowed to sleep at all. They may only wait for jobs or groups they have created and enqueued (otherwise this would easily dead-lock). See Wait() or GetResult() for more details.

Note
By default the job system assumes that all jobs of a group share the same dependencies (because they operate on the same data) and single jobs share dependencies when they use the same code (again because they likely use the same data). Furthermore jobs enqueued to the main thread queue are assumed to have a UI dependency by default. For the unlikely case of requiring custom dependencies const JobDependencyGroupInterface* GetDependencyGroup() const can be implemented by your jobs to return a shared dependency group.
class AJobWithCustomDependencies : public JobInterfaceTemplate<AJobWithCustomDependencies>
{
public:
Result<void> operator ()() { ... }
const JobDependencyGroupInterface* GetDependencyGroup() const { return g_mySharedDependencies; }
};

Public Member Functions

JOBOPTIONFLAGS GetJobOptions () const
 
const CharGetName () const
 
 JobInterface (const JobInterfaceJumpTablePOD &jmpTable)
 
 ~JobInterface ()
 
 JobInterface (JobInterface &&src)
 
JobInterfaceoperator= (JobInterface &&src)
 
Bool Wait (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< void > GetResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< void > MoveResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT)
 
void Cancel ()
 
Bool IsCancelled () const
 
void CancelAndWait (WAITMODE mode=WAITMODE::DEFAULT)
 
JobInterfaceEnqueue (JobQueueInterface *queue=JOBQUEUE_CURRENT)
 
Result< void > AddSubJob (JobInterface *subJob)
 
template<typename JOB >
Result< void > AddSubJob (ResultMemT< JOB * > subJob)
 
template<typename JOBREF >
Result< void > AddSubJob (ResultMemT< JOBREF > &&subJob)
 
template<typename GROUP >
Result< void > AddSubGroup (GROUP *subGroup)
 
template<typename GROUP >
Result< void > AddSubGroup (ResultMemT< GROUP * > subGroup)
 
template<typename GROUP >
Result< void > AddSubGroup (ResultMemT< GROUP > subGroup)
 
JobGroupInterfaceGetJobGroup () const
 
ObservableFinishedBase< JobInterfaceObservableFinished ()
 
ObservableCancelledBase< JobInterfaceObservableCancelled ()
 
Result< void > Then (JobInterface *next, JobQueueInterface *queue=JOBQUEUE_CURRENT)
 
String ToString (const FormatStatement *formatStatement=nullptr) const
 

Static Public Member Functions

static Int GetCurrentWorkerThreadIndex ()
 
static Int GetCurrentThreadCount ()
 
static Bool IsCurrentJobCancelled (const JobInterface *optionalJob=nullptr)
 
static JobStatusInterfaceGetCurrentJob ()
 

Private Member Functions

 MAXON_DISALLOW_COPY_AND_ASSIGN (JobInterface)
 

Static Private Member Functions

template<typename IMPLEMENTATION >
static IMPLEMENTATION & GetWorker (const JobInterface *job)
 
template<typename IMPLEMENTATION >
static void * DestructWorker (const JobInterface *self)
 
template<typename IMPLEMENTATION >
static const ErrorInterfaceRunWorker (const JobInterface *job)
 
template<typename T >
static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::false_type *)
 
template<typename T >
static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::true_type *)
 
template<typename IMPLEMENTATION >
static const JobDependencyGroupInterface * GetWorkerDependencyGroup (const JobInterface *job)
 
template<typename IMPLEMENTATION >
static void * GetWorkerOptions (const JobInterface *self, Int selector, void *param)
 
static CoreJobGroup & GetCoreJobGroup (JobGroupInterface *group)
 

Friends

class StrongRefHandler
 
template<typename >
struct ObservableFinishedBase
 
template<typename >
struct ObservableCancelledBase
 
class JobStatusInterface
 
class JobGroupInterface
 
template<typename >
class StaticJobGroupInterface
 
class TimerInterface
 
template<typename FN >
auto ExecuteOnMainThread (FN &&fn, WAITMODE waitMode, TimeValue wait) -> decltype(fn())