mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 04:23:35 +02:00
um: Add pthread-based helper support
Introduce a new set of utility functions that can be used to create pthread-based helpers. Helper threads created in this way will ensure thread safety for errno while sharing the same memory space. Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com> Link: https://patch.msgid.link/20250319135523.97050-2-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
16a0ca5e4e
commit
4f087eafdc
|
|
@ -224,6 +224,11 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
|
|||
unsigned int flags, unsigned long *stack_out);
|
||||
extern int helper_wait(int pid);
|
||||
|
||||
struct os_helper_thread;
|
||||
int os_run_helper_thread(struct os_helper_thread **td_out,
|
||||
void *(*routine)(void *), void *arg);
|
||||
void os_kill_helper_thread(struct os_helper_thread *td);
|
||||
void os_fix_helper_thread_signals(void);
|
||||
|
||||
/* umid.c */
|
||||
extern int umid_file_name(char *name, char *buf, int len);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
|
@ -167,3 +168,65 @@ int helper_wait(int pid)
|
|||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct os_helper_thread {
|
||||
pthread_t handle;
|
||||
};
|
||||
|
||||
int os_run_helper_thread(struct os_helper_thread **td_out,
|
||||
void *(*routine)(void *), void *arg)
|
||||
{
|
||||
struct os_helper_thread *td;
|
||||
sigset_t sigset, oset;
|
||||
int err, flags;
|
||||
|
||||
flags = __uml_cant_sleep() ? UM_GFP_ATOMIC : UM_GFP_KERNEL;
|
||||
td = uml_kmalloc(sizeof(*td), flags);
|
||||
if (!td)
|
||||
return -ENOMEM;
|
||||
|
||||
sigfillset(&sigset);
|
||||
if (sigprocmask(SIG_SETMASK, &sigset, &oset) < 0) {
|
||||
err = -errno;
|
||||
kfree(td);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = pthread_create(&td->handle, NULL, routine, arg);
|
||||
|
||||
if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
|
||||
panic("Failed to restore the signal mask: %d", errno);
|
||||
|
||||
if (err != 0)
|
||||
kfree(td);
|
||||
else
|
||||
*td_out = td;
|
||||
|
||||
return -err;
|
||||
}
|
||||
|
||||
void os_kill_helper_thread(struct os_helper_thread *td)
|
||||
{
|
||||
pthread_cancel(td->handle);
|
||||
pthread_join(td->handle, NULL);
|
||||
kfree(td);
|
||||
}
|
||||
|
||||
void os_fix_helper_thread_signals(void)
|
||||
{
|
||||
sigset_t sigset;
|
||||
|
||||
sigemptyset(&sigset);
|
||||
|
||||
sigaddset(&sigset, SIGWINCH);
|
||||
sigaddset(&sigset, SIGPIPE);
|
||||
sigaddset(&sigset, SIGPROF);
|
||||
sigaddset(&sigset, SIGINT);
|
||||
sigaddset(&sigset, SIGTERM);
|
||||
sigaddset(&sigset, SIGCHLD);
|
||||
sigaddset(&sigset, SIGALRM);
|
||||
sigaddset(&sigset, SIGIO);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user