libfuse3: Use negative logic for pthread cancelation
to avoid race condition.
This commit is contained in:
parent
bf556291eb
commit
78a624ab54
|
@ -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=3.12.0
|
||||
TERMUX_PKG_REVISION=1
|
||||
TERMUX_PKG_SRCURL=https://github.com/libfuse/libfuse/archive/fuse-${TERMUX_PKG_VERSION}.tar.gz
|
||||
TERMUX_PKG_SHA256=df6cc8807c4fd36b6b0ebef2b738dad6d19a9c7c085ccc3775063688d0bfcc0b
|
||||
|
||||
|
|
|
@ -8,26 +8,24 @@
|
|||
|
||||
/*
|
||||
* fsel_open_mask is used to limit the number of opens to 1 per file.
|
||||
@@ -220,7 +221,8 @@ static void *fsel_producer(void *data)
|
||||
@@ -220,7 +221,7 @@ static void *fsel_producer(void *data)
|
||||
const struct timespec interval = { 0, 250000000 };
|
||||
unsigned idx = 0, nr = 1;
|
||||
|
||||
- (void) data;
|
||||
+ atomic_flag *cancel = (atomic_flag *) data;
|
||||
+ atomic_flag_clear(cancel);
|
||||
|
||||
while (1) {
|
||||
int i, t;
|
||||
@@ -257,6 +259,8 @@ static void *fsel_producer(void *data)
|
||||
@@ -257,6 +258,7 @@ static void *fsel_producer(void *data)
|
||||
|
||||
pthread_mutex_unlock(&fsel_mutex);
|
||||
|
||||
+ if (atomic_flag_test_and_set(cancel)) pthread_exit(NULL);
|
||||
+ atomic_flag_clear(cancel);
|
||||
+ if (!atomic_flag_test_and_set(cancel)) pthread_exit(NULL);
|
||||
nanosleep(&interval, NULL);
|
||||
}
|
||||
|
||||
@@ -268,6 +272,7 @@ int main(int argc, char *argv[])
|
||||
@@ -268,6 +270,7 @@ int main(int argc, char *argv[])
|
||||
pthread_t producer;
|
||||
pthread_attr_t attr;
|
||||
int ret;
|
||||
|
@ -35,21 +33,22 @@
|
|||
|
||||
errno = pthread_mutex_init(&fsel_mutex, NULL);
|
||||
if (errno) {
|
||||
@@ -281,7 +286,7 @@ int main(int argc, char *argv[])
|
||||
@@ -281,7 +284,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
- errno = pthread_create(&producer, &attr, fsel_producer, NULL);
|
||||
+ atomic_flag_test_and_set(&cancel);
|
||||
+ errno = pthread_create(&producer, &attr, fsel_producer, (void *)&cancel);
|
||||
if (errno) {
|
||||
perror("pthread_create");
|
||||
return 1;
|
||||
@@ -289,7 +294,7 @@ int main(int argc, char *argv[])
|
||||
@@ -289,7 +293,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
ret = fuse_main(argc, argv, &fsel_oper, NULL);
|
||||
|
||||
- pthread_cancel(producer);
|
||||
+ atomic_flag_test_and_set(&cancel);
|
||||
+ atomic_flag_clear(&cancel);
|
||||
pthread_join(producer, NULL);
|
||||
|
||||
return ret;
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#define FUSE_NODE_SLAB 1
|
||||
|
||||
@@ -128,6 +129,7 @@ struct fuse {
|
||||
@@ -127,6 +128,7 @@ struct fuse {
|
||||
struct list_head partial_slabs;
|
||||
struct list_head full_slabs;
|
||||
pthread_t prune_thread;
|
||||
|
@ -16,25 +16,32 @@
|
|||
};
|
||||
|
||||
struct lock {
|
||||
@@ -4843,9 +4845,12 @@ static void *fuse_prune_nodes(void *fuse)
|
||||
{
|
||||
struct fuse *f = fuse;
|
||||
int sleep_time;
|
||||
+ atomic_flag_clear(&f->cancel);
|
||||
@@ -4881,6 +4883,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;
|
||||
@@ -4863,7 +4868,7 @@ void fuse_stop_cleanup_thread(struct fuse *f)
|
||||
@@ -4888,8 +4891,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;
|
||||
}
|
||||
@@ -4898,7 +4903,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);
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
/* Environment var controlling the thread stack size */
|
||||
#define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK"
|
||||
@@ -39,6 +40,7 @@ struct fuse_worker {
|
||||
@@ -45,6 +46,7 @@ struct fuse_worker {
|
||||
struct fuse_buf fbuf;
|
||||
struct fuse_chan *ch;
|
||||
struct fuse_mt *mt;
|
||||
|
@ -16,30 +16,31 @@
|
|||
};
|
||||
|
||||
struct fuse_mt {
|
||||
@@ -118,14 +120,15 @@ 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)) {
|
||||
@@ -130,9 +132,8 @@ static void *fuse_do_work(void *data)
|
||||
int isforget = 0;
|
||||
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_int(mt->se, &w->fbuf, w->ch);
|
||||
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
if (res == -EINTR)
|
||||
continue;
|
||||
if (res <= 0) {
|
||||
@@ -333,7 +336,7 @@ int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *co
|
||||
@@ -297,6 +298,7 @@ static int fuse_loop_start_thread(struct
|
||||
}
|
||||
}
|
||||
|
||||
+ atomic_flag_test_and_set(&w->cancel);
|
||||
res = fuse_start_thread(&w->thread_id, fuse_do_work, w);
|
||||
if (res == -1) {
|
||||
fuse_chan_put(w->ch);
|
||||
@@ -364,7 +366,7 @@ int err;
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue