Parcourir la source

Alexandre Oliva writes:

The vfork() wrapper defined in libpthread, that's used to run
pthread_atfork()-registered handlers, is not only a very bad idea,
it's broken and useless.  Here's the rationale:

[---------snip----------]

Since the implementation as it stands is broken (linking a program
that vfork()s and exec()s on the child and wait()s on the parent works
unless you happen to link with libpthread), and I can't think of
any workable solution, I suggest that we simply remove the vfork()
overrider in the non-MMU case.  Yes, we might lose some small amount
of functionality here, but it's not like people running uClinux expect
anything resembling actual fork() to work.
Eric Andersen il y a 20 ans
Parent
commit
201ca767d5
1 fichiers modifiés avec 16 ajouts et 21 suppressions
  1. 16 21
      libpthread/linuxthreads/ptfork.c

+ 16 - 21
libpthread/linuxthreads/ptfork.c

@@ -17,6 +17,9 @@
 /* The "atfork" stuff */
 
 #include <errno.h>
+
+#ifdef __ARCH_HAS_MMU__
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -74,7 +77,7 @@ static inline void pthread_call_handlers(struct handler_list * list)
 {
   for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
 }
-#ifdef __ARCH_HAS_MMU__
+
 extern int __libc_fork(void);
 
 pid_t __fork(void)
@@ -105,27 +108,19 @@ pid_t __vfork(void)
   return __fork();
 }
 weak_alias (__vfork, vfork);
+
 #else
-pid_t __vfork(void)
-{
-  pid_t pid;
-  struct handler_list * prepare, * child, * parent;
 
-  pthread_mutex_lock(&pthread_atfork_lock);
-  prepare = pthread_atfork_prepare;
-  child = pthread_atfork_child;
-  parent = pthread_atfork_parent;
-  pthread_mutex_unlock(&pthread_atfork_lock);
-  pthread_call_handlers(prepare);
-  pid = __libc_vfork();
-  if (pid == 0) {
-    __pthread_reset_main_thread();
-    __fresetlockfiles();
-    pthread_call_handlers(child);
-  } else {
-    pthread_call_handlers(parent);
-  }
-  return pid;
+/* We can't support pthread_atfork without MMU, since we don't have
+   fork(), and we can't offer the correct semantics for vfork().  */
+int pthread_atfork(void (*prepare)(void),
+		   void (*parent)(void),
+		   void (*child)(void))
+{
+  /* ENOMEM is probably pushing it a little bit.
+     Take it as `no *virtual* memory' :-)  */
+  errno = ENOMEM;
+  return -1;
 }
-weak_alias (__vfork, vfork);
+
 #endif