VLC  4.0.0-dev
Data Structures | Functions
executor.c File Reference
Include dependency graph for executor.c:

Data Structures

struct  vlc_executor_thread
 An executor can spawn several threads. More...
 
struct  vlc_executor
 The executor (also vlc_executor_t, exposed as opaque type in the public header). More...
 

Functions

static void QueuePush (vlc_executor_t *executor, struct vlc_runnable *runnable)
 
static struct vlc_runnableQueueTake (vlc_executor_t *executor)
 
static void * ThreadRun (void *userdata)
 
static int SpawnThread (vlc_executor_t *executor)
 
vlc_executor_tvlc_executor_New (unsigned max_threads)
 Create a new executor. More...
 
void vlc_executor_Submit (vlc_executor_t *executor, struct vlc_runnable *runnable)
 Submit a runnable for execution. More...
 
bool vlc_executor_Cancel (vlc_executor_t *executor, struct vlc_runnable *runnable)
 Cancel a runnable previously submitted. More...
 
void vlc_executor_WaitIdle (vlc_executor_t *executor)
 Wait until all submitted tasks are completed or canceled. More...
 
void vlc_executor_Delete (vlc_executor_t *executor)
 Delete an executor. More...
 

Function Documentation

◆ QueuePush()

static void QueuePush ( vlc_executor_t executor,
struct vlc_runnable runnable 
)
static

◆ QueueTake()

static struct vlc_runnable* QueueTake ( vlc_executor_t executor)
static

◆ SpawnThread()

static int SpawnThread ( vlc_executor_t executor)
static

◆ ThreadRun()

static void* ThreadRun ( void *  userdata)
static

◆ vlc_executor_Cancel()

bool vlc_executor_Cancel ( vlc_executor_t executor,
struct vlc_runnable runnable 
)

Cancel a runnable previously submitted.

If this runnable is still queued (i.e. it has not be run yet), then dequeue it so that it will never be run, and return true.

Otherwise, this runnable has already been taken by an executor thread (it is still running or is complete). In that case, do nothing, and return false.

This is an error to pass a runnable not submitted to this executor (the result is undefined in that case).

Note that the runnable instance is owned by the caller, so the executor will never attempt to free it.

Parameters
executorthe executor
runnablethe task to cancel
Return values
trueif the runnable has been canceled before execution
falseif the runnable has not been canceled

References vlc_executor::idle_wait, vlc_executor::lock, vlc_list::next, vlc_runnable::node, vlc_list::prev, vlc_executor::unfinished, vlc_cond_signal(), vlc_list_remove(), vlc_mutex_lock(), and vlc_mutex_unlock().

Referenced by CancelAllTasks(), and input_preparser_Cancel().

◆ vlc_executor_Delete()

void vlc_executor_Delete ( vlc_executor_t executor)

Delete an executor.

Wait for all the threads to complete, and delete the executor instance.

All submitted tasks must be either started or explicitly canceled. To wait for all tasks to complete, use vlc_executor_WaitIdle().

It is an error to submit a new runnable after vlc_executor_Delete() is called. In particular, a running task must not submit a new runnable once deletion has been requested.

Parameters
executorthe executor

Referenced by input_fetcher_Delete(), input_fetcher_New(), input_preparser_Delete(), and vlc_thumbnailer_Release().

◆ vlc_executor_New()

vlc_executor_t* vlc_executor_New ( unsigned  max_threads)

Create a new executor.

Parameters
max_threadsthe maximum number of threads used to execute runnables
Returns
a pointer to a new executor, or NULL if an error occurred

References vlc_executor::closing, vlc_executor::idle_wait, vlc_executor::lock, vlc_executor::max_threads, vlc_executor::nthreads, vlc_executor::queue, vlc_executor::queue_wait, SpawnThread(), vlc_executor::threads, vlc_executor::unfinished, vlc_cond_init(), vlc_list_init(), vlc_mutex_init(), and VLC_SUCCESS.

Referenced by input_fetcher_New(), input_preparser_New(), and vlc_thumbnailer_Create().

◆ vlc_executor_Submit()

void vlc_executor_Submit ( vlc_executor_t executor,
struct vlc_runnable runnable 
)

Submit a runnable for execution.

The struct vlc_runnable is not copied, it must exist until the end of the execution (the user is expected to embed it in its own task structure).

Here is a simple example:

struct my_task {
char *str;
struct vlc_runnable runnable;
};
static void Run(void *userdata)
{
struct my_task *task = userdata;
printf("start of %s\n", task->str);
vlc_tick_sleep(VLC_TICK_FROM_SEC(3)); // long action
printf("end of %s\n", task->str);
free(task->str);
free(task);
}
void foo(vlc_executor_t *executor, const char *str)
{
// no error handling for brevity
struct my_task *task = malloc(sizeof(*task));
task->str = strdup(str);
}
void vlc_executor_Submit(vlc_executor_t *executor, struct vlc_runnable *runnable)
Submit a runnable for execution.
Definition: executor.c:206
#define vlc_tick_sleep(d)
Definition: vlc_threads.h:853
static void * Run(void *)
Definition: input.c:459
Definition: fetcher.c:54
struct vlc_runnable runnable
to be passed to the executor
Definition: fetcher.c:64
The executor (also vlc_executor_t, exposed as opaque type in the public header).
Definition: executor.c:55
A Runnable encapsulates a task to be run from an executor thread.
Definition: vlc_executor.h:38
void(* run)(void *userdata)
This function is to be executed by a vlc_executor_t.
Definition: vlc_executor.h:55
void * userdata
Userdata passed back to run().
Definition: vlc_executor.h:60
char * strdup(const char *)
#define VLC_TICK_FROM_SEC(sec)
Definition: vlc_tick.h:54

A runnable instance is intended to be submitted at most once. The caller is expected to allocate a new task structure (embedding the runnable) for every submission.

More precisely, it is incorrect to submit a runnable already submitted that is still in the pending queue (i.e. not canceled or started). This is due to the intrusive linked list of runnables.

It is strongly discouraged to submit a runnable that is currently running on the executor (unless you are prepared for the run() callback to be run several times in parallel).

For simplicity, it is discouraged to submit a runnable previously submitted.

Parameters
executorthe executor
runnablethe task to run

References vlc_executor::closing, vlc_executor::lock, vlc_executor::max_threads, vlc_executor::nthreads, QueuePush(), SpawnThread(), vlc_executor::unfinished, vlc_mutex_lock(), and vlc_mutex_unlock().

Referenced by input_preparser_Push(), RequestCommon(), and Submit().

◆ vlc_executor_WaitIdle()

void vlc_executor_WaitIdle ( vlc_executor_t executor)

Wait until all submitted tasks are completed or canceled.

Parameters
executorthe executor

References vlc_executor::idle_wait, vlc_executor::lock, vlc_executor::unfinished, vlc_cond_wait(), vlc_mutex_lock(), and vlc_mutex_unlock().