Bug 799805 - Avoid using bionic's fork(), r=cjones
authorMichael Wu <mwu@mozilla.com>
Thu, 25 Oct 2012 19:34:06 -0400
changeset 119647 9e99e11d6ef6b38b9decf26d4da992a290ecd278
parent 119646 73a1b4cc15cc2f849de52c648f51f955482a8f89
child 119648 4051d30c8f35ee5aa5579531d8f243e1586d9201
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs799805
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 799805 - Avoid using bionic's fork(), r=cjones
configure.in
mozglue/build/BionicGlue.cpp
mozglue/build/Makefile.in
mozglue/build/cpuacct.c
mozglue/build/cpuacct.h
--- a/configure.in
+++ b/configure.in
@@ -7148,17 +7148,20 @@ AC_SUBST(DLLFLAGS)
 dnl We need to wrap dlopen and related functions on Android because we use
 dnl our own linker.
 if test "$OS_TARGET" = Android; then
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozglue"
     if test -n "$MOZ_OLD_LINKER"; then
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
     fi
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
-    WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=fork,--wrap=pthread_atfork,--wrap=raise,--wrap=PR_GetEnv,--wrap=PR_SetEnv"
+    WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl--wrap=PR_GetEnv,--wrap=PR_SetEnv"
+    if test -z "$gonkdir"; then
+        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=fork,--wrap=pthread_atfork,--wrap=raise"
+    fi
 fi
 
 dnl ========================================================
 dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
--- a/mozglue/build/BionicGlue.cpp
+++ b/mozglue/build/BionicGlue.cpp
@@ -1,67 +1,90 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <pthread.h>
 #include <string.h>
+#include <stdlib.h>
+#include <time.h>
 #include <unistd.h>
+#include <android/log.h>
 
 #include <vector>
 
 #define NS_EXPORT __attribute__ ((visibility("default")))
 
 /* Android doesn't have pthread_atfork(), so we need to use our own. */
 struct AtForkFuncs {
   void (*prepare)(void);
   void (*parent)(void);
   void (*child)(void);
 };
 static std::vector<AtForkFuncs> atfork;
 
+#ifdef MOZ_WIDGET_GONK
+#include "cpuacct.h"
+#define WRAP(x) x
+
 extern "C" NS_EXPORT int
-__wrap_pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
+timer_create(clockid_t, struct sigevent*, timer_t*)
+{
+  __android_log_print(ANDROID_LOG_ERROR, "BionicGlue", "timer_create not supported!");
+  abort();
+  return -1;
+}
+
+#else
+#define cpuacct_add(x)
+#define WRAP(x) __wrap_##x
+#endif
+
+extern "C" NS_EXPORT int
+WRAP(pthread_atfork)(void (*prepare)(void), void (*parent)(void), void (*child)(void))
 {
   AtForkFuncs funcs;
   funcs.prepare = prepare;
   funcs.parent = parent;
   funcs.child = child;
   atfork.push_back(funcs);
   return 0;
 }
 
+extern "C" pid_t __fork(void);
+
 extern "C" NS_EXPORT pid_t
-__wrap_fork(void)
+WRAP(fork)(void)
 {
   pid_t pid;
   for (std::vector<AtForkFuncs>::reverse_iterator it = atfork.rbegin();
        it < atfork.rend(); ++it)
     if (it->prepare)
       it->prepare();
 
-  switch ((pid = fork())) {
+  switch ((pid = __fork())) {
   case 0:
+    cpuacct_add(getuid());
     for (std::vector<AtForkFuncs>::iterator it = atfork.begin();
          it < atfork.end(); ++it)
       if (it->child)
         it->child();
     break;
   default:
     for (std::vector<AtForkFuncs>::iterator it = atfork.begin();
          it < atfork.end(); ++it)
       if (it->parent)
         it->parent();
   }
   return pid;
 }
 
 extern "C" NS_EXPORT int
-__wrap_raise(int sig)
+WRAP(raise)(int sig)
 {
   return pthread_kill(pthread_self(), sig);
 }
 
 /*
  * The following wrappers for PR_Xxx are needed until we can get
  * PR_DuplicateEnvironment landed in NSPR.
  * See see bug 772734 and bug 773414.
--- a/mozglue/build/Makefile.in
+++ b/mozglue/build/Makefile.in
@@ -56,26 +56,30 @@ ifneq (,$(filter -DEFAULTLIB:mozcrt,$(MO
 # Don't install the import library if we use mozcrt
 NO_INSTALL_IMPORT_LIBRARY = 1
 endif
 
 EXTRA_DSO_LDOPTS += $(MOZ_ZLIB_LIBS)
 endif
 
 ifeq (Android,$(OS_TARGET))
-# To properly wrap jemalloc's pthread_atfork call.
-EXTRA_DSO_LDOPTS += -Wl,--wrap=pthread_atfork
 CPPSRCS += BionicGlue.cpp
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,android,$(DEPTH)/other-licenses/android)
 endif
 
 ifeq (android, $(MOZ_WIDGET_TOOLKIT))
 # Add Android specific code
 EXTRA_DSO_LDOPTS += $(MOZ_ZLIB_LIBS)
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,android,../android)
+# To properly wrap jemalloc's pthread_atfork call.
+EXTRA_DSO_LDOPTS += -Wl,--wrap=pthread_atfork
+endif
+
+ifeq (gonk, $(MOZ_WIDGET_TOOLKIT))
+CSRCS += cpuacct.c
 endif
 
 ifdef MOZ_LINKER
 # Add custom dynamic linker
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,linker,../linker)
 
 ifeq (arm, $(TARGET_CPU))
 EXTRA_DSO_LDOPTS += -Wl,-version-script,$(srcdir)/arm-eabi-filter
new file mode 100644
--- /dev/null
+++ b/mozglue/build/cpuacct.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "cpuacct.h"
+
+int cpuacct_add(uid_t uid)
+{
+    int count;
+    int fd;
+    char buf[80];
+
+    count = snprintf(buf, sizeof(buf), "/acct/uid/%d/tasks", uid);
+    fd = open(buf, O_RDWR|O_CREAT|O_TRUNC|O_SYNC);
+    if (fd < 0) {
+        /* Note: sizeof("tasks") returns 6, which includes the NULL char */
+        buf[count - sizeof("tasks")] = 0;
+        if (mkdir(buf, 0775) < 0)
+            return -errno;
+
+        /* Note: sizeof("tasks") returns 6, which includes the NULL char */
+        buf[count - sizeof("tasks")] = '/';
+        fd = open(buf, O_RDWR|O_CREAT|O_TRUNC|O_SYNC);
+    }
+    if (fd < 0)
+        return -errno;
+
+    write(fd, "0", 2);
+    if (close(fd))
+        return -errno;
+
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/mozglue/build/cpuacct.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BIONIC_CPUACCT_H
+#define _BIONIC_CPUACCT_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+extern int cpuacct_add(uid_t uid);
+
+__END_DECLS
+
+#endif /* _BIONIC_CPUACCT_H */