Back to index

glibc  2.9
ptfork.c
Go to the documentation of this file.
00001 /* Linuxthreads - a simple clone()-based implementation of Posix        */
00002 /* threads for Linux.                                                   */
00003 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
00004 /*                                                                      */
00005 /* This program is free software; you can redistribute it and/or        */
00006 /* modify it under the terms of the GNU Library General Public License  */
00007 /* as published by the Free Software Foundation; either version 2       */
00008 /* of the License, or (at your option) any later version.               */
00009 /*                                                                      */
00010 /* This program is distributed in the hope that it will be useful,      */
00011 /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
00012 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
00013 /* GNU Library General Public License for more details.                 */
00014 
00015 /* The "atfork" stuff */
00016 
00017 #include <errno.h>
00018 #include <stddef.h>
00019 #include <stdlib.h>
00020 #include <unistd.h>
00021 #include "pthread.h"
00022 #include "internals.h"
00023 #include <bits/libc-lock.h>
00024 #include "fork.h"
00025 
00026 extern int __libc_fork (void);
00027 
00028 pid_t __pthread_fork (struct fork_block *b)
00029 {
00030   pid_t pid;
00031   list_t *runp;
00032 
00033   __libc_lock_lock (b->lock);
00034 
00035   /* Run all the registered preparation handlers.  In reverse order.  */
00036   list_for_each_prev (runp, &b->prepare_list)
00037     {
00038       struct fork_handler *curp;
00039       curp = list_entry (runp, struct fork_handler, list);
00040       curp->handler ();
00041     }
00042 
00043   __pthread_once_fork_prepare();
00044   __flockfilelist();
00045 
00046   pid = ARCH_FORK ();
00047 
00048   if (pid == 0) {
00049     __pthread_reset_main_thread();
00050 
00051     __fresetlockfiles();
00052     __pthread_once_fork_child();
00053 
00054     /* Run the handlers registered for the child.  */
00055     list_for_each (runp, &b->child_list)
00056       {
00057        struct fork_handler *curp;
00058        curp = list_entry (runp, struct fork_handler, list);
00059        curp->handler ();
00060       }
00061 
00062     __libc_lock_init (b->lock);
00063   } else {
00064     __funlockfilelist();
00065     __pthread_once_fork_parent();
00066 
00067     /* Run the handlers registered for the parent.  */
00068     list_for_each (runp, &b->parent_list)
00069       {
00070        struct fork_handler *curp;
00071        curp = list_entry (runp, struct fork_handler, list);
00072        curp->handler ();
00073       }
00074 
00075     __libc_lock_unlock (b->lock);
00076   }
00077 
00078   return pid;
00079 }
00080 
00081 #ifdef SHARED
00082 pid_t __fork (void)
00083 {
00084   return __libc_fork ();
00085 }
00086 weak_alias (__fork, fork);
00087 
00088 pid_t __vfork(void)
00089 {
00090   return __libc_fork ();
00091 }
00092 weak_alias (__vfork, vfork);
00093 #endif