VLC 4.0.0-dev
No Matches
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...


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.
void vlc_executor_Submit (vlc_executor_t *executor, struct vlc_runnable *runnable)
 Submit a runnable for execution.
bool vlc_executor_Cancel (vlc_executor_t *executor, struct vlc_runnable *runnable)
 Cancel a runnable previously submitted.
void vlc_executor_WaitIdle (vlc_executor_t *executor)
 Wait until all submitted tasks are completed or canceled.
void vlc_executor_Delete (vlc_executor_t *executor)
 Delete an executor.

Function Documentation

◆ QueuePush()

◆ QueueTake()

◆ SpawnThread()

◆ ThreadRun()

◆ 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.

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(), vlc_preparser_Cancel(), and vlc_thumbnailer_DestroyRequest().

◆ 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.

executorthe executor

References vlc_executor::closing, vlc_executor::lock, vlc_executor_thread::node, vlc_executor::queue, vlc_executor::queue_wait, vlc_thread::thread, thread, vlc_executor::threads, vlc_executor::unfinished, vlc_cond_broadcast(), vlc_join(), vlc_list_foreach, vlc_list_is_empty(), vlc_mutex_lock(), and vlc_mutex_unlock().

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

◆ vlc_executor_New()

vlc_executor_t * vlc_executor_New ( unsigned  max_threads)

Create a new executor.

max_threadsthe maximum number of threads used to execute runnables
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(), vlc_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);
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:210
void() vlc_tick_sleep(vlc_tick_t delay)
Waits for an interval of time.
Definition thread.c:222
static void * Run(void *)
Definition input.c:409
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:56

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.

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 RequestCommon(), Submit(), and vlc_preparser_Push().

◆ vlc_executor_WaitIdle()

void vlc_executor_WaitIdle ( vlc_executor_t executor)

Wait until all submitted tasks are completed or canceled.

executorthe executor

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