0
0
mirror of https://github.com/termux/termux-packages.git synced 2024-11-21 20:56:19 +00:00
termux-packages/disabled-packages/btrfs-progs/pthread_cancel.patch
Tee KOBAYASHI 5e28960e54 btrfs-progs: Disabled
Upstream has explicitly removed support for Android and we are not going
to maintain this on our own.
2022-12-07 23:24:17 +00:00

322 lines
7.0 KiB
Diff

--- a/cmds/rescue-chunk-recover.c
+++ b/cmds/rescue-chunk-recover.c
@@ -25,6 +25,9 @@
#include <errno.h>
#include <stddef.h>
#include <string.h>
+#ifdef __ANDROID__
+#include <stdatomic.h>
+#endif
#include "kernel-lib/list.h"
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
@@ -78,6 +81,9 @@
struct btrfs_device *dev;
int fd;
u64 bytenr;
+#ifdef __ANDROID__
+ atomic_flag thread_running;
+#endif
};
static struct extent_record *btrfs_new_extent_record(struct extent_buffer *eb)
@@ -728,6 +734,15 @@
return 0;
}
+#ifdef __ANDROID__
+#define PTHREAD_CANCELED ((void *)-1)
+
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(PTHREAD_CANCELED);
+}
+#endif
+
static int scan_one_device(void *dev_scan_struct)
{
struct extent_buffer *buf;
@@ -737,15 +752,28 @@
struct recover_control *rc = dev_scan->rc;
struct btrfs_device *device = dev_scan->dev;
int fd = dev_scan->fd;
+#ifndef __ANDROID__
int oldtype;
ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
if (ret)
return 1;
+#else
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+#endif
buf = malloc(sizeof(*buf) + rc->nodesize);
- if (!buf)
+ if (!buf) {
+#ifdef __ANDROID__
+ atomic_flag_clear(&dev_scan->thread_running);
+#endif
return -ENOMEM;
+ }
buf->len = rc->nodesize;
bytenr = 0;
@@ -806,6 +834,9 @@
out:
close(fd);
free(buf);
+#ifdef __ANDROID__
+ atomic_flag_clear(&dev_scan->thread_running);
+#endif
return ret;
}
@@ -852,6 +883,9 @@
dev_scans[devidx].dev = dev;
dev_scans[devidx].fd = fd;
dev_scans[devidx].bytenr = -1;
+#ifdef __ANDROID__
+ atomic_flag_test_and_set(&dev_scans[devidx].thread_running);
+#endif
devidx++;
}
@@ -870,8 +904,15 @@
for (i = 0; i < devidx; i++) {
if (dev_scans[i].bytenr == -1)
continue;
+#ifndef __ANDROID__
ret = pthread_tryjoin_np(t_scans[i],
(void **)&t_rets[i]);
+#else
+ if (atomic_flag_test_and_set(&dev_scans[i].thread_running))
+ ret = EBUSY;
+ else
+ ret = pthread_join(t_scans[i], (void **)&t_rets[i]);
+#endif
if (ret == EBUSY) {
all_done = false;
continue;
@@ -908,7 +949,11 @@
for (i = 0; i < devidx; i++) {
if (dev_scans[i].bytenr == -1)
continue;
+#ifndef __ANDROID__
pthread_cancel(t_scans[i]);
+#else
+ pthread_kill(t_scans[i], SIGUSR2);
+#endif
}
out2:
free(dev_scans);
--- a/cmds/scrub.c
+++ b/cmds/scrub.c
@@ -843,11 +843,18 @@
int fd = -1;
int old;
+#ifndef __ANDROID__
ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);
if (ret) {
err = -ret;
goto out3;
}
+#else
+ sigset_t pthread_cancel_block;
+ sigemptyset(&pthread_cancel_block);
+ sigaddset(&pthread_cancel_block, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &pthread_cancel_block, NULL);
+#endif
ret = pthread_mutex_lock(m);
if (ret) {
@@ -879,9 +886,13 @@
err = -ret;
out2:
+#ifndef __ANDROID__
ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
if (ret && !err)
err = -ret;
+#else
+ sigprocmask(SIG_UNBLOCK, &pthread_cancel_block, NULL);
+#endif
out3:
return err;
@@ -930,6 +941,15 @@
return NULL;
}
+#ifdef __ANDROID__
+#define PTHREAD_CANCELED ((void *)-1)
+
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(PTHREAD_CANCELED);
+}
+#endif
+
/* nb: returns a negative errno via ERR_PTR */
static void *scrub_progress_cycle(void *ctx)
{
@@ -959,9 +979,22 @@
struct sockaddr_un peer;
socklen_t peer_size = sizeof(peer);
+#ifndef __ANDROID__
perr = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
if (perr)
goto out;
+#else
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+
+ sigset_t pthread_cancel_block;
+ sigemptyset(&pthread_cancel_block);
+ sigaddset(&pthread_cancel_block, SIGUSR2);
+#endif
uuid_unparse(spc->fi->fsid, fsid);
@@ -1013,10 +1046,14 @@
* result we got for the current write and go
* on. flag should be set on next cycle, then.
*/
+#ifndef __ANDROID__
perr = pthread_setcancelstate(
PTHREAD_CANCEL_DISABLE, &old);
if (perr)
goto out;
+#else
+ sigprocmask(SIG_BLOCK, &pthread_cancel_block, NULL);
+#endif
perr = pthread_mutex_lock(&sp_shared->progress_mutex);
if (perr)
goto out;
@@ -1025,20 +1062,28 @@
&sp_shared->progress_mutex);
if (perr)
goto out;
+#ifndef __ANDROID__
perr = pthread_setcancelstate(
PTHREAD_CANCEL_ENABLE, &old);
if (perr)
goto out;
+#else
+ sigprocmask(SIG_UNBLOCK, &pthread_cancel_block, NULL);
+#endif
memcpy(sp, sp_last, sizeof(*sp));
continue;
}
perr = pthread_mutex_unlock(&sp_shared->progress_mutex);
if (perr)
goto out;
+#ifndef __ANDROID__
perr = pthread_setcancelstate(
PTHREAD_CANCEL_ENABLE, &old);
if (perr)
goto out;
+#else
+ sigprocmask(SIG_UNBLOCK, &pthread_cancel_block, NULL);
+#endif
memcpy(sp, sp_shared, sizeof(*sp));
memcpy(sp_last, sp_shared, sizeof(*sp));
}
@@ -1567,7 +1612,11 @@
}
}
+#ifndef __ANDROID__
ret = pthread_cancel(t_prog);
+#else
+ ret = pthread_kill(t_prog, SIGUSR2);
+#endif
if (!ret)
ret = pthread_join(t_prog, &terr);
--- a/common/task-utils.c
+++ b/common/task-utils.c
@@ -36,6 +36,39 @@
return info;
}
+#ifdef __ANDROID__
+typedef struct wrapped_thread_start {
+ void *(*start)(void *);
+ void *arg;
+} wrapped_thread_start_t;
+
+#define PTHREAD_CANCELED ((void *)-1)
+
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(PTHREAD_CANCELED);
+}
+
+static void *pthread_create_wrapper(void *wrapped_arg)
+{
+ wrapped_thread_start_t *wrapped_start = (wrapped_thread_start_t *)wrapped_arg;
+
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+
+ void *(*start)(void *) = wrapped_start->start;
+ void *arg = wrapped_start->arg;
+
+ free(wrapped_start);
+
+ return (*start)(arg);
+}
+#endif
+
int task_start(struct task_info *info, time_t *start_time, u64 *item_count)
{
int ret;
@@ -51,8 +84,20 @@
if (item_count)
*item_count = 0;
+#ifndef __ANDROID__
ret = pthread_create(&info->id, NULL, info->threadfn,
info->private_data);
+#else
+ wrapped_thread_start_t *wrapped_start = malloc(sizeof(wrapped_thread_start_t));
+ if (wrapped_start == NULL)
+ ret = errno;
+ else {
+ wrapped_start->start = info->threadfn;
+ wrapped_start->arg = info->private_data;
+ ret = pthread_create(&info->id, NULL, pthread_create_wrapper,
+ wrapped_start);
+ }
+#endif
if (ret)
info->id = 0;
@@ -66,7 +111,11 @@
return;
if (info->id) {
+#ifndef __ANDROID__
pthread_cancel(info->id);
+#else
+ pthread_kill(info->id, SIGUSR2);
+#endif
pthread_join(info->id, NULL);
info->id = 0;
}