libfuse2: Use negative logic for pthread cancelation

to avoid race condition.
This commit is contained in:
Tee KOBAYASHI 2022-12-13 07:38:46 +09:00 committed by xtkoba
parent 729d04f152
commit bf556291eb
3 changed files with 31 additions and 28 deletions

View File

@ -3,6 +3,7 @@ TERMUX_PKG_DESCRIPTION="FUSE (Filesystem in Userspace) is an interface for users
TERMUX_PKG_LICENSE="LGPL-2.1, GPL-2.0"
TERMUX_PKG_MAINTAINER="Henrik Grimler @Grimler91"
TERMUX_PKG_VERSION=2.9.9
TERMUX_PKG_REVISION=1
TERMUX_PKG_SRCURL=https://github.com/libfuse/libfuse/archive/fuse-${TERMUX_PKG_VERSION}.tar.gz
TERMUX_PKG_SHA256=e57a24721177c3b3dd71cb9239ca46b4dee283db9388d48f7ccd256184982194
TERMUX_PKG_DEPENDS="libiconv"

View File

@ -1,7 +1,5 @@
diff --git a/lib/fuse.c b/../fuse.c
index d1d873a..c3ddf68 100644
--- a/lib/fuse.c
+++ b/../fuse.c
+++ b/lib/fuse.c
@@ -38,6 +38,7 @@
#include <sys/time.h>
#include <sys/mman.h>
@ -18,25 +16,32 @@ index d1d873a..c3ddf68 100644
};
struct lock {
@@ -4637,9 +4639,12 @@ static void *fuse_prune_nodes(void *fuse)
{
struct fuse *f = fuse;
int sleep_time;
+ atomic_flag_clear(&f->cancel);
@@ -4640,6 +4642,7 @@ static void *fuse_prune_nodes(void *fuse
while(1) {
sleep_time = fuse_clean_cache(f);
+ if (atomic_flag_test_and_set(&f->cancel)) pthread_exit(NULL);
+ atomic_flag_clear(&f->cancel);
+ if (!atomic_flag_test_and_set(&f->cancel)) pthread_exit(NULL);
sleep(sleep_time);
}
return NULL;
@@ -4657,7 +4662,7 @@ void fuse_stop_cleanup_thread(struct fuse *f)
@@ -4647,8 +4650,10 @@ static void *fuse_prune_nodes(void *fuse
int fuse_start_cleanup_thread(struct fuse *f)
{
- if (lru_enabled(f))
+ if (lru_enabled(f)) {
+ atomic_flag_test_and_set(&f->cancel);
return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
+ }
return 0;
}
@@ -4657,7 +4662,7 @@ void fuse_stop_cleanup_thread(struct fus
{
if (lru_enabled(f)) {
pthread_mutex_lock(&f->lock);
- pthread_cancel(f->prune_thread);
+ atomic_flag_test_and_set(&f->cancel);
+ atomic_flag_clear(&f->cancel);
pthread_mutex_unlock(&f->lock);
pthread_join(f->prune_thread, NULL);
}

View File

@ -1,7 +1,5 @@
diff --git a/lib/fuse_loop_mt.c b/../fuse_loop_mt.c
index 82e3001..005639a 100644
--- a/lib/fuse_loop_mt.c
+++ b/../fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -19,6 +19,7 @@
#include <semaphore.h>
#include <errno.h>
@ -18,32 +16,31 @@ index 82e3001..005639a 100644
};
struct fuse_mt {
@@ -67,6 +69,7 @@ static void *fuse_do_work(void *data)
{
struct fuse_worker *w = (struct fuse_worker *) data;
struct fuse_mt *mt = w->mt;
+ atomic_flag_clear(&w->cancel);
while (!fuse_session_exited(mt->se)) {
int isforget = 0;
@@ -77,9 +80,9 @@ static void *fuse_do_work(void *data)
@@ -77,9 +79,8 @@ static void *fuse_do_work(void *data)
};
int res;
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ if (atomic_flag_test_and_set(&w->cancel)) pthread_exit(NULL);
+ atomic_flag_clear(&w->cancel);
+ if (!atomic_flag_test_and_set(&w->cancel)) pthread_exit(NULL);
res = fuse_session_receive_buf(mt->se, &fbuf, &ch);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (res == -EINTR)
continue;
if (res <= 0) {
@@ -243,7 +246,7 @@ int fuse_session_loop_mt(struct fuse_session *se)
@@ -193,6 +194,7 @@ static int fuse_loop_start_thread(struct
return -1;
}
+ atomic_flag_test_and_set(&w->cancel);
res = fuse_start_thread(&w->thread_id, fuse_do_work, w);
if (res == -1) {
free(w->buf);
@@ -243,7 +245,7 @@ int fuse_session_loop_mt(struct fuse_ses
pthread_mutex_lock(&mt.lock);
for (w = mt.main.next; w != &mt.main; w = w->next)
- pthread_cancel(w->thread_id);
+ atomic_flag_test_and_set(&w->cancel);
+ atomic_flag_clear(&w->cancel);
mt.exit = 1;
pthread_mutex_unlock(&mt.lock);