diff options
author | jb <jb@FreeBSD.org> | 1998-03-09 06:54:50 +0000 |
---|---|---|
committer | jb <jb@FreeBSD.org> | 1998-03-09 06:54:50 +0000 |
commit | aba00ab374621025c49c80b7b6e9a347807ea59a (patch) | |
tree | e4cfd2d05c25232382f90ebdc7b3f8801bee131d /lib | |
parent | 57eab44cdf9ffdde0c0474dae3eb964c3aec98c3 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | lib/libc_r/uthread/uthread_fork.c | 39 | ||||
-rw-r--r-- | lib/libkse/thread/thr_fork.c | 39 | ||||
-rw-r--r-- | lib/libpthread/thread/thr_fork.c | 39 |
3 files changed, 117 insertions, 0 deletions
diff --git a/lib/libc_r/uthread/uthread_fork.c b/lib/libc_r/uthread/uthread_fork.c index 19f674d..89d7259 100644 --- a/lib/libc_r/uthread/uthread_fork.c +++ b/lib/libc_r/uthread/uthread_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); } diff --git a/lib/libkse/thread/thr_fork.c b/lib/libkse/thread/thr_fork.c index 19f674d..89d7259 100644 --- a/lib/libkse/thread/thr_fork.c +++ b/lib/libkse/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); } 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); } |