summaryrefslogtreecommitdiff
path: root/lib/pthreadpool/pthreadpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pthreadpool/pthreadpool.c')
-rw-r--r--lib/pthreadpool/pthreadpool.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/pthreadpool/pthreadpool.c b/lib/pthreadpool/pthreadpool.c
index 528f4cdfd67..127e684c63e 100644
--- a/lib/pthreadpool/pthreadpool.c
+++ b/lib/pthreadpool/pthreadpool.c
@@ -112,10 +112,13 @@ struct pthreadpool {
* where the forking thread will unlock it again.
*/
pthread_mutex_t fork_mutex;
+
+ bool per_thread_cwd;
};
static pthread_mutex_t pthreadpools_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct pthreadpool *pthreadpools = NULL;
+static bool pthreadpool_support_thread_cwd = false;
static pthread_once_t pthreadpool_atfork_initialized = PTHREAD_ONCE_INIT;
static void pthreadpool_prep_atfork(void);
@@ -182,6 +185,11 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
pool->max_threads = max_threads;
pool->num_idle = 0;
pool->prefork_cond = NULL;
+ if (max_threads != 0) {
+ pool->per_thread_cwd = pthreadpool_support_thread_cwd;
+ } else {
+ pool->per_thread_cwd = false;
+ }
ret = pthread_mutex_lock(&pthreadpools_mutex);
if (ret != 0) {
@@ -241,6 +249,15 @@ size_t pthreadpool_queued_jobs(struct pthreadpool *pool)
return ret;
}
+bool pthreadpool_per_thread_cwd(struct pthreadpool *pool)
+{
+ if (pool->stopped) {
+ return false;
+ }
+
+ return pool->per_thread_cwd;
+}
+
static void pthreadpool_prepare_pool(struct pthreadpool *pool)
{
int ret;
@@ -359,6 +376,16 @@ static void pthreadpool_child(void)
static void pthreadpool_prep_atfork(void)
{
+#ifdef HAVE_UNSHARE_CLONE_FS
+ int res;
+
+ /* remember if unshare(CLONE_FS) works. */
+ res = unshare(CLONE_FS);
+ if (res == 0) {
+ pthreadpool_support_thread_cwd = true;
+ }
+#endif
+
pthread_atfork(pthreadpool_prepare, pthreadpool_parent,
pthreadpool_child);
}
@@ -571,6 +598,13 @@ static void *pthreadpool_server(void *arg)
struct pthreadpool *pool = (struct pthreadpool *)arg;
int res;
+#ifdef HAVE_UNSHARE_CLONE_FS
+ if (pool->per_thread_cwd) {
+ res = unshare(CLONE_FS);
+ assert(res == 0);
+ }
+#endif
+
res = pthread_mutex_lock(&pool->mutex);
if (res != 0) {
return NULL;