tools: update CMake to 3.17.0
[vlc.git] / src / misc / background_worker.h
1 /*****************************************************************************
2  * Copyright (C) 2017 VLC authors and VideoLAN
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
17  *****************************************************************************/
18
19 #ifndef BACKGROUND_WORKER_H__
20 #define BACKGROUND_WORKER_H__
21
22 struct background_worker_config {
23     /**
24      * Default timeout for completing a task
25      *
26      * If less-than 0 a task can run indefinitely without being killed, whereas
27      * a positive value denotes the maximum number of milliseconds a task can
28      * run before \ref pf_stop is called to kill it.
29      **/
30     vlc_tick_t default_timeout;
31
32     /**
33      * Maximum number of threads used to execute tasks.
34      */
35     int max_threads;
36
37     /**
38      * Release an entity
39      *
40      * This callback will be called in order to decrement the ref-count of a
41      * entity within the background-worker. It will happen either when \ref
42      * pf_stop has finished executing, or if the entity is removed from the
43      * queue (through \ref background_worker_Cancel)
44      *
45      * \warning As each task might be executed in parallel by different threads,
46      *          this callback must be thread-safe.
47      *
48      * \param entity the entity to release
49      **/
50     void( *pf_release )( void* entity );
51
52     /**
53      * Hold a queued item
54      *
55      * This callback will be called in order to increment the ref-count of an
56      * entity. It will happen when the entity is pushed into the queue of
57      * pending tasks as part of \ref background_worker_Push.
58      *
59      * \warning As each task might be executed in parallel by different threads,
60      *          this callback must be thread-safe.
61      *
62      * \param entity the entity to hold
63      **/
64     void( *pf_hold )( void* entity );
65
66     /**
67      * Start a new task
68      *
69      * This callback is called in order to construct a new background task. In
70      * order for the background-worker to be able to continue processing
71      * incoming requests, \ref pf_start is meant to start a task (such as a
72      * thread), and then store the associated handle in `*out`.
73      *
74      * The value of `*out` will then be the value of the argument named `handle`
75      * in terms of \ref pf_probe and \ref pf_stop.
76      *
77      * \warning As each task might be executed in parallel by different threads,
78      *          this callback must be thread-safe.
79      *
80      * \param owner the owner of the background-worker
81      * \param entity the entity for which a task is to be created
82      * \param out [out] `*out` shall, on success, refer to the handle associated
83      *                   with the running task.
84      * \return VLC_SUCCESS if a task was created, an error-code on failure.
85      **/
86     int( *pf_start )( void* owner, void* entity, void** out );
87
88     /**
89      * Probe a running task
90      *
91      * This callback is called in order to see whether or not a running task has
92      * finished or not. It can be called anytime between a successful call to
93      * \ref pf_start, and the corresponding call to \ref pf_stop.
94      *
95      * \warning As each task might be executed in parallel by different threads,
96      *          this callback must be thread-safe.
97      *
98      * \param owner the owner of the background-worker
99      * \param handle the handle associated with the running task
100      * \return 0 if the task is still running, any other value if finished.
101      **/
102     int( *pf_probe )( void* owner, void* handle );
103
104     /**
105      * Stop a running task
106      *
107      * This callback is called in order to stop a running task. If \ref pf_start
108      * has created a non-detached thread, \ref pf_stop is where you would
109      * interrupt and then join it.
110      *
111      * \warning This function is called either after \ref pf_probe has stated
112      *          that the task has finished, or if the timeout (if any) for the
113      *          task has been reached.
114      *
115      * \warning As each task might be executed in parallel by different threads,
116      *          this callback must be thread-safe.
117      *
118      * \param owner the owner of the background-worker
119      * \parma handle the handle associated with the task to be stopped
120      **/
121     void( *pf_stop )( void* owner, void* handle );
122 };
123
124 /**
125  * Create a background-worker
126  *
127  * This function creates a new background-worker using the passed configuration.
128  *
129  * \warning all members of `config` shall have been set by the caller.
130  * \warning the returned resource must be destroyed using \ref
131  *          background_worker_Delete on success.
132  *
133  * \param owner the owner of the background-worker
134  * \param config the background-worker's configuration
135  * \return a pointer-to the created background-worker on success,
136  *         `NULL` on failure.
137  **/
138 struct background_worker* background_worker_New( void* owner,
139     struct background_worker_config* config );
140
141 /**
142  * Request the background-worker to probe the current task
143  *
144  * This function is used to signal the background-worker that it should do
145  * another probe to see whether the current task is still alive.
146  *
147  * \warning Note that the function will not wait for the probing to finish, it
148  *          will simply ask the background worker to recheck it as soon as
149  *          possible.
150  *
151  * \param worker the background-worker
152  **/
153 void background_worker_RequestProbe( struct background_worker* worker );
154
155 /**
156  * Push an entity into the background-worker
157  *
158  * This function is used to push an entity into the queue of pending work. The
159  * entities will be processed in the order in which they are received (in terms
160  * of the order of invocations in a single-threaded environment).
161  *
162  * \param worker the background-worker
163  * \param entity the entity which is to be queued
164  * \param id a value suitable for identifying the entity, or `NULL`
165  * \param timeout the timeout of the entity in milliseconds, `0` denotes no
166  *                timeout, a negative value will use the default timeout
167  *                associated with the background-worker.
168  * \return VLC_SUCCESS if the entity was successfully queued, an error-code on
169  *         failure.
170  **/
171 int background_worker_Push( struct background_worker* worker, void* entity,
172     void* id, int timeout );
173
174 /**
175  * Remove entities from the background-worker
176  *
177  * This function is used to remove processing of a certain entity given its
178  * associated id, or to remove all queued (including currently running)
179  * entities.
180  *
181  * \warning if the `id` passed refers to an entity that is currently being
182  *          processed, the call will block until the task has been terminated.
183  *
184  * \param worker the background-worker
185  * \param id NULL if every entity shall be removed, and the currently running
186  *        task (if any) shall be cancelled.
187  **/
188 void background_worker_Cancel( struct background_worker* worker, void* id );
189
190 /**
191  * Delete a background-worker
192  *
193  * This function will destroy a background-worker created through \ref
194  * background_worker_New. It will effectively stop the currently running task,
195  * if any, and empty the queue of pending entities.
196  *
197  * \warning If there is a currently running task, the function will block until
198  *          it has been stopped.
199  *
200  * \param worker the background-worker
201  **/
202 void background_worker_Delete( struct background_worker* worker );
203 #endif