summaryrefslogtreecommitdiffstats
path: root/lib/libpthread
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>1998-03-09 06:54:50 +0000
committerjb <jb@FreeBSD.org>1998-03-09 06:54:50 +0000
commitaba00ab374621025c49c80b7b6e9a347807ea59a (patch)
treee4cfd2d05c25232382f90ebdc7b3f8801bee131d /lib/libpthread
parent57eab44cdf9ffdde0c0474dae3eb964c3aec98c3 (diff)
downloadFreeBSD-src-aba00ab374621025c49c80b7b6e9a347807ea59a.zip
FreeBSD-src-aba00ab374621025c49c80b7b6e9a347807ea59a.tar.gz
When forking a process, only the running thread gets to live. All
other threads never see the light of day and if they leave things locked, blame POSIX.
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/thread/thr_fork.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thr_fork.c b/lib/libpthread/thread/thr_fork.c
index 19f674d..89d7259 100644
--- a/lib/libpthread/thread/thr_fork.c
+++ b/lib/libpthread/thread/thr_fork.c
@@ -42,7 +42,13 @@ pid_t
fork(void)
{
int flags;
+ int status;
pid_t ret;
+ pthread_t pthread;
+ pthread_t pthread_next;
+
+ /* Block signals to avoid being interrupted at a bad time: */
+ _thread_kern_sig_block(&status);
/* Fork a new process: */
if ((ret = _thread_sys_fork()) <= 0) {
@@ -83,9 +89,42 @@ fork(void)
else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
/* Abort this application: */
abort();
+ } else {
+ /* Point to the first thread in the list: */
+ pthread = _thread_link_list;
+
+ /*
+ * Enter a loop to remove all threads other than
+ * the running thread from the thread list:
+ */
+ while (pthread != NULL) {
+ pthread_next = pthread->nxt;
+ if (pthread == _thread_run) {
+ _thread_link_list = pthread;
+ pthread->nxt = NULL;
+ } else {
+ if (pthread->attr.stackaddr_attr ==
+ NULL && pthread->stack != NULL) {
+ /*
+ * Free the stack of the
+ * dead thread:
+ */
+ free(pthread->stack);
+ }
+ if (pthread->specific_data != NULL)
+ free(pthread->specific_data);
+ free(pthread);
+ }
+
+ /* Point to the next thread: */
+ pthread = pthread_next;
+ }
}
}
+ /* Unblock signals: */
+ _thread_kern_sig_unblock(&status);
+
/* Return the process ID: */
return (ret);
}
OpenPOWER on IntegriCloud