[vlc-devel] [RFC 1/2] executor: introduce new executor API
Rémi Denis-Courmont
remi at remlab.net
Wed Aug 26 21:01:19 CEST 2020
Le keskiviikkona 26. elokuuta 2020, 20.19.56 EEST Romain Vimont a écrit :
> +/**
> + * Create a new executor.
> + *
> + * \param parent a VLC object
> + * \param max_threads the maximum number of threads used to execute
> runnables + * \return a pointer to a new executor, or NULL if an error
> occurred + */
> +VLC_API vlc_executor_t *
> +vlc_executor_New(vlc_object_t *parent, unsigned max_threads);
Don't really get why a VLC object is needed here. This can be limiting for
what's supposed to be a generic helper.
> + * \code{c}
> + * static void Run(void *userdata)
> + * {
> + * char *str = userdata;
> + * printf("start of %s\n", str);
> + * sleep(3);
ONCE AGAIN, sleep is not portably thread-safe. This is not a good example.
> + * printf("end of %s\n", str);
> + * }
> + * void foo(vlc_executor_t *executor, const char *name)
> + * {
> + * // error handling replaced by assertions for brevity
> + * char *str = strdup(name);
> + * assert(str);
Example code should not assume !defined(NDEBUG) either.
> + * int ret = vlc_executor_Submit(executor, &runnable, str, NULL, 0);
> + * assert(ret == VLC_SUCCESS);
> + * }
> + * \endcode
> +VLC_API int
> +vlc_executor_Submit(vlc_executor_t *executor,
> + const struct vlc_runnable *runnable, void *userdata,
> + void *id, vlc_tick_t timeout);
Type name for works and workers really ought to be in the same semantic field
IMO.
It is unlikely that callers will (or even should have to) handle errors well
at this point.
> +/**
> + * Cancel all submitted tasks having the specified id.
> + *
> + * If id is NULL, then cancel all tasks.
> + *
> + * If may_interrupt_if_running is true, then the current running tasks may
> be + * interrupted using the interrupt() callback.
> + *
> + * \param executor the executor
> + * \param id the id of the tasks to cancel (NULL for all tasks)
> + * \param may_interrupt_if_running indicate if the tasks currently running
> may + * be interrupted
> + */
> +VLC_API void
> +vlc_executor_Cancel(vlc_executor_t *executor, void *id,
> + bool may_interrupt_if_running);
Two separate external functions may be easier to read than a bool.
> diff --git a/src/misc/executor.c b/src/misc/executor.c
> new file mode 100644
> index 0000000000..88c7064b72
> +/**
> + * Make sure that an interrupt thread is running and will consider the
> + * interruption for a new task just added.
> + */
> +static int
> +RequireInterruptThread(vlc_executor_t *executor)
> +{
> + vlc_mutex_assert(&executor->lock);
> +
> + if (executor->interrupt_thread_running)
> + vlc_cond_signal(&executor->interrupt_wait);
> + else
> + {
> + if (vlc_clone_detach(NULL, InterruptThreadRun, executor,
> + VLC_THREAD_PRIORITY_LOW))
Detached threads cannot be safe in dynamically linked LibVLC. There's a risk
that LibVLC will be unloaded before the thread exits, crashing the process.
> + {
> + vlc_mutex_unlock(&executor->lock);
> + return VLC_EGENERIC;
You probably can't do that since you're not handling errors at the call site.
> + }
> +
> + executor->interrupt_thread_running = true;
> + }
> +
> + return VLC_SUCCESS;
> +}
--
雷米‧德尼-库尔蒙
http://www.remlab.net/
More information about the vlc-devel
mailing list