pthreadpool: call unshare(CLONE_FS) if available
[samba.git] / lib / pthreadpool / pthreadpool.h
1 /*
2  * Unix SMB/CIFS implementation.
3  * threadpool implementation based on pthreads
4  * Copyright (C) Volker Lendecke 2009,2011
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifndef __PTHREADPOOL_H__
21 #define __PTHREADPOOL_H__
22
23 struct pthreadpool;
24
25 /**
26  * @defgroup pthreadpool The pthreadpool API
27  *
28  * This API provides a way to run threadsafe functions in a helper
29  * thread. It is initially intended to run getaddrinfo asynchronously.
30  */
31
32
33 /**
34  * @brief Create a pthreadpool
35  *
36  * A struct pthreadpool is the basis for for running threads in the
37  * background.
38  *
39  * @param[in]   max_threads     Maximum parallelism in this pool
40  * @param[out]  presult         Pointer to the threadpool returned
41  * @return                      success: 0, failure: errno
42  *
43  * max_threads=0 means unlimited parallelism. The caller has to take
44  * care to not overload the system.
45  */
46 int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
47                      int (*signal_fn)(int jobid,
48                                       void (*job_fn)(void *private_data),
49                                       void *job_fn_private_data,
50                                       void *private_data),
51                      void *signal_fn_private_data);
52
53 /**
54  * @brief Get the max threads value of pthreadpool
55  *
56  * @note This can be 0 for strict sync processing.
57  *
58  * @param[in]   pool            The pool
59  * @return                      number of possible threads
60  */
61 size_t pthreadpool_max_threads(struct pthreadpool *pool);
62
63 /**
64  * @brief The number of queued jobs of pthreadpool
65  *
66  * This is the number of jobs added by pthreadpool_add_job(),
67  * which are not yet processed by a thread.
68  *
69  * @param[in]   pool            The pool
70  * @return                      The number of jobs
71  */
72 size_t pthreadpool_queued_jobs(struct pthreadpool *pool);
73
74 /**
75  * @brief Check for per thread current working directory support of pthreadpool
76  *
77  * Since Linux kernel 2.6.16, unshare(CLONE_FS) is supported,
78  * which provides a per thread current working directory
79  * and allows [f]chdir() within the worker threads.
80  *
81  * Note that this doesn't work on some contraint container setups,
82  * the complete unshare() syscall might be rejected.
83  * pthreadpool_per_thread_cwd() returns what is available
84  * at runtime, so the callers should really check this!
85  *
86  * @param[in]   pool            The pool to run the job on
87  * @return                      supported: true, otherwise: false
88  */
89 bool pthreadpool_per_thread_cwd(struct pthreadpool *pool);
90
91 /**
92  * @brief Stop a pthreadpool
93  *
94  * Stop a pthreadpool. If jobs are submitted, but not yet active in
95  * a thread, they won't get executed. If a job has already been
96  * submitted to a thread, the job function will continue running, and
97  * the signal function might still be called.
98  *
99  * This allows a multi step shutdown using pthreadpool_stop(),
100  * pthreadpool_cancel_job() and pthreadpool_destroy().
101  *
102  * @param[in]   pool            The pool to stop
103  * @return                      success: 0, failure: errno
104  *
105  * @see pthreadpool_cancel_job()
106  * @see pthreadpool_destroy()
107  */
108 int pthreadpool_stop(struct pthreadpool *pool);
109
110 /**
111  * @brief Destroy a pthreadpool
112  *
113  * This basically implies pthreadpool_stop() if the pool
114  * isn't already stopped.
115  *
116  * Destroy a pthreadpool. If jobs are submitted, but not yet active in
117  * a thread, they won't get executed. If a job has already been
118  * submitted to a thread, the job function will continue running, and
119  * the signal function might still be called. The caller of
120  * pthreadpool_init must make sure the required resources are still
121  * around when the pool is destroyed with pending jobs.  The last
122  * thread to exit will finally free() the pool memory.
123  *
124  * @param[in]   pool            The pool to destroy
125  * @return                      success: 0, failure: errno
126  *
127  * @see pthreadpool_stop()
128  */
129 int pthreadpool_destroy(struct pthreadpool *pool);
130
131 /**
132  * @brief Add a job to a pthreadpool
133  *
134  * This adds a job to a pthreadpool. The job can be identified by
135  * job_id. This integer will be passed to signal_fn() when the
136  * job is completed.
137  *
138  * @param[in]   pool            The pool to run the job on
139  * @param[in]   job_id          A custom identifier
140  * @param[in]   fn              The function to run asynchronously
141  * @param[in]   private_data    Pointer passed to fn
142  * @return                      success: 0, failure: errno
143  */
144 int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
145                         void (*fn)(void *private_data), void *private_data);
146
147 /**
148  * @brief Try to cancel a job in a pthreadpool
149  *
150  * This tries to cancel a job in a pthreadpool. The same
151  * arguments, which were given to pthreadpool_add_job()
152  * needs to be passed.
153  *
154  * The combination of id, fn, private_data might not be unique.
155  * So the function tries to cancel as much matching jobs as possible.
156  * Note once a job is scheduled in a thread it's to late to
157  * cancel it.
158  *
159  * Canceled jobs that weren't started yet won't be reported via a
160  * pool's signal_fn.
161  *
162  * @param[in]   pool            The pool to run the job on
163  * @param[in]   job_id          A custom identifier
164  * @param[in]   fn              The function to run asynchronously
165  * @param[in]   private_data    Pointer passed to fn
166  * @return                      The number of canceled jobs
167  *
168  * @see pthreadpool_add_job()
169  * @see pthreadpool_stop()
170  * @see pthreadpool_destroy()
171  */
172 size_t pthreadpool_cancel_job(struct pthreadpool *pool, int job_id,
173                               void (*fn)(void *private_data), void *private_data);
174
175 #endif