Bug 799805 - Avoid using bionic's fork(), r=cjones
authorMichael Wu <mwu@mozilla.com>
Thu, 25 Oct 2012 19:34:06 -0400
changeset 111844 9e99e11d6ef6b38b9decf26d4da992a290ecd278
parent 111843 73a1b4cc15cc2f849de52c648f51f955482a8f89
child 111845 4051d30c8f35ee5aa5579531d8f243e1586d9201
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewerscjones
bugs799805
milestone19.0a1
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 */