Przeglądaj źródła

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 20 lat temu
rodzic
commit
201ca767d5
1 zmienionych plików z 16 dodań i 21 usunięć
  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