049e47d543dffe6f8e576cac640b18d6ec2b7185
[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      * Release an entity
34      *
35      * This callback will be called in order to decrement the ref-count of a
36      * entity within the background-worker. It will happen either when \ref
37      * pf_stop has finished executing, or if the entity is removed from the
38      * queue (through \ref background_worker_Cancel)
39      *
40      * \param entity the entity to release
41      **/
42     void( *pf_release )( void* entity );
43
44     /**
45      * Hold a queued item
46      *
47      * This callback will be called in order to increment the ref-count of an
48      * entity. It will happen when the entity is pushed into the queue of
49      * pending tasks as part of \ref background_worker_Push.
50      *
51      * \param entity the entity to hold
52      **/
53     void( *pf_hold )( void* entity );
54
55     /**
56      * Start a new task
57      *
58      * This callback is called in order to construct a new background task. In
59      * order for the background-worker to be able to continue processing
60      * incoming requests, \ref pf_start is meant to start a task (such as a
61      * thread), and then store the associated handle in `*out`.
62      *
63      * The value of `*out` will then be the value of the argument named `handle`
64      * in terms of \ref pf_probe and \ref pf_stop.
65      *
66      * \param owner the owner of the background-worker
67      * \param entity the entity for which a task is to be created
68      * \param out [out] `*out` shall, on success, refer to the handle associated
69      *                   with the running task.
70      * \return VLC_SUCCESS if a task was created, an error-code on failure.
71      **/
72     int( *pf_start )( void* owner, void* entity, void** out );
73
74     /**
75      * Probe a running task
76      *
77      * This callback is called in order to see whether or not a running task has
78      * finished or not. It can be called anytime between a successful call to
79      * \ref pf_start, and the corresponding call to \ref pf_stop.
80      *
81      * \param owner the owner of the background-worker
82      * \param handle the handle associated with the running task
83      * \return 0 if the task is still running, any other value if finished.
84      **/
85     int( *pf_probe )( void* owner, void* handle );
86
87     /**
88      * Stop a running task
89      *
90      * This callback is called in order to stop a running task. If \ref pf_start
91      * has created a non-detached thread, \ref pf_stop is where you would
92      * interrupt and then join it.
93      *
94      * \warning This function is called either after \ref pf_probe has stated
95      *          that the task has finished, or if the timeout (if any) for the
96      *          task has been reached.
97      *
98      * \param owner the owner of the background-worker
99      * \parma handle the handle associated with the task to be stopped
100      **/
101     void( *pf_stop )( void* owner, void* handle );
102 };
103
104 /**
105  * Create a background-worker
106  *
107  * This function creates a new background-worker using the passed configuration.
108  *
109  * \warning all members of `config` shall have been set by the caller.
110  * \warning the returned resource must be destroyed using \ref
111  *          background_worker_Delete on success.
112  *
113  * \param owner the owner of the background-worker
114  * \param config the background-worker's configuration
115  * \return a pointer-to the created background-worker on success,
116  *         `NULL` on failure.
117  **/
118 struct background_worker* background_worker_New( void* owner,
119     struct background_worker_config* config );
120
121 /**
122  * Request the background-worker to probe the current task
123  *
124  * This function is used to signal the background-worker that it should do
125  * another probe to see whether the current task is still alive.
126  *
127  * \warning Note that the function will not wait for the probing to finish, it
128  *          will simply ask the background worker to recheck it as soon as
129  *          possible.
130  *
131  * \param worker the background-worker
132  **/
133 void background_worker_RequestProbe( struct background_worker* worker );
134
135 /**
136  * Push an entity into the background-worker
137  *
138  * This function is used to push an entity into the queue of pending work. The
139  * entities will be processed in the order in which they are received (in terms
140  * of the order of invocations in a single-threaded environment).
141  *
142  * \param worker the background-worker
143  * \param entity the entity which is to be queued
144  * \param id a value suitable for identifying the entity, or `NULL`
145  * \param timeout the timeout of the entity in milliseconds, `0` denotes no
146  *                timeout, a negative value will use the default timeout
147  *                associated with the background-worker.
148  * \return VLC_SUCCESS if the entity was successfully queued, an error-code on
149  *         failure.
150  **/
151 int background_worker_Push( struct background_worker* worker, void* entity,
152     void* id, int timeout );
153
154 /**
155  * Remove entities from the background-worker
156  *
157  * This function is used to remove processing of a certain entity given its
158  * associated id, or to remove all queued (including currently running)
159  * entities.
160  *
161  * \warning if the `id` passed refers to an entity that is currently being
162  *          processed, the call will block until the task has been terminated.
163  *
164  * \param worker the background-worker
165  * \param id NULL if every entity shall be removed, and the currently running
166  *        task (if any) shall be cancelled.
167  **/
168 void background_worker_Cancel( struct background_worker* worker, void* id );
169
170 /**
171  * Delete a background-worker
172  *
173  * This function will destroy a background-worker created through \ref
174  * background_worker_New. It will effectively stop the currently running task,
175  * if any, and empty the queue of pending entities.
176  *
177  * \warning If there is a currently running task, the function will block until
178  *          it has been stopped.
179  *
180  * \param worker the background-worker
181  **/
182 void background_worker_Delete( struct background_worker* worker );
183 #endif