1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

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.
This commit is contained in:
John Birrell 1998-03-09 06:54:50 +00:00
parent e7b6782c39
commit 9dbdb44326
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=34381
3 changed files with 117 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}