mozglue/build/Nuwa.h
author Jim Blandy <jimb@mozilla.com>
Tue, 24 Jun 2014 22:12:07 -0700
changeset 199513 69d61e42d5dfbf4588b72449249ff3e7f2125304
parent 151489 eeda15041decf2126f33d81caba03c25950992bf
child 228269 ccac54007b1e399cb4f80387c88afcefce98e29d
permissions -rw-r--r--
Bug 914753: Make Emacs file variable header lines correct, or at least consistent. DONTBUILD r=ehsan The -*- file variable lines -*- establish per-file settings that Emacs will pick up. This patch makes the following changes to those lines (and touches nothing else): - Never set the buffer's mode. Years ago, Emacs did not have a good JavaScript mode, so it made sense to use Java or C++ mode in .js files. However, Emacs has had js-mode for years now; it's perfectly serviceable, and is available and enabled by default in all major Emacs packagings. Selecting a mode in the -*- file variable line -*- is almost always the wrong thing to do anyway. It overrides Emacs's default choice, which is (now) reasonable; and even worse, it overrides settings the user might have made in their '.emacs' file for that file extension. It's only useful when there's something specific about that particular file that makes a particular mode appropriate. - Correctly propagate settings that establish the correct indentation level for this file: c-basic-offset and js2-basic-offset should be js-indent-level. Whatever value they're given should be preserved; different parts of our tree use different indentation styles. - We don't use tabs in Mozilla JS code. Always set indent-tabs-mode: nil. Remove tab-width: settings, at least in files that don't contain tab characters. - Remove js2-mode settings that belong in the user's .emacs file, like js2-skip-preprocessor-directives.

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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/. */

#ifndef __NUWA_H_
#define __NUWA_H_

#include <setjmp.h>
#include <unistd.h>

#include "mozilla/Types.h"

/**
 * Nuwa is a goddess who created mankind according to her figure in the
 * ancient Chinese mythology.
 */

// Max number of top level protocol that can be handled by Nuwa process.
#ifndef NUWA_TOPLEVEL_MAX
#define NUWA_TOPLEVEL_MAX 8
#endif

struct NuwaProtoFdInfo {
    int protoId;
    int originFd;
    int newFds[2];
};

#define NUWA_NEWFD_PARENT 0
#define NUWA_NEWFD_CHILD 1

extern "C" {

/**
 * The following 3 methods are used to synchronously spawn the Nuwa process.
 * The typical usage is:
 *
 *   The IPC thread                                The main thread
 *   1. Receives the request.
 *   2. NuwaSpawnPrepare().
 *   3. Request main thread to
 *      spawn. --------------------------------------+
 *   4. NuwaSpawnWait().                             V
 *                                                 5. NuwaSpawn() to clone all
 *                                                    the threads in the Nuwa
 *                                                    process (including main
 *                                                    & IPC threads).
 *                                                 6. NuwaSpawn() finishes and
 *            +-------------------------------------- signals NuwaSpawnWait().
 *            V
 *   7. NuwaSpawnWait() returns.
 */

/**
 * Prepare for spawning a new process. The calling thread (typically the IPC
 * thread) will block further requests to spawn a new process.
 */
MFBT_API void NuwaSpawnPrepare();

/**
 * Called on the thread that receives the request. Used to wait until
 * NuwaSpawn() finishes and maintain the stack of the calling thread.
 */
MFBT_API void NuwaSpawnWait();

/**
 * Spawn a new content process, called in the Nuwa process. This has to run on
 * the main thread.
 *
 * @return The process ID of the new process.
 */
MFBT_API pid_t NuwaSpawn();

/**
 * The following methods are for marking threads created in the Nuwa process so
 * they can be frozen and then recreated in the spawned process. All threads
 * except the main thread must be marked by one of the following 4 methods;
 * otherwise, we have a thread that is created but unknown to us. The Nuwa
 * process will never become ready and this needs to be fixed.
 */

/**
 * Mark the current thread as supporting Nuwa. The thread will implicitly freeze
 * by calling a blocking method such as pthread_mutex_lock() or epoll_wait().
 *
 * @param recreate The custom function that will be called in the spawned
 *                 process, after the thread is recreated. Can be nullptr if no
 *                 custom function to be called after the thread is recreated.
 * @param arg The argument passed to the custom function. Can be nullptr.
 */
MFBT_API void NuwaMarkCurrentThread(void (*recreate)(void *), void *arg);

/**
 * Mark the current thread as not supporting Nuwa. The calling thread will not
 * be automatically cloned from the Nuwa process to spawned process. If this
 * thread needs to be created in the spawned process, use NuwaAddConstructor()
 * or NuwaAddFinalConstructor() to do it.
 */
MFBT_API void NuwaSkipCurrentThread();

/**
 * Force the current thread to freeze explicitly at the current point.
 */
MFBT_API void NuwaFreezeCurrentThread();

/**
 * Helper functions for the NuwaCheckpointCurrentThread() macro.
 */
MFBT_API jmp_buf* NuwaCheckpointCurrentThread1();

MFBT_API bool NuwaCheckpointCurrentThread2(int setjmpCond);

/**
 * Set the point to recover after thread recreation. The calling thread is not
 * blocked. This is used for the thread that cannot freeze (i.e. the IPC
 * thread).
 */
#define NuwaCheckpointCurrentThread() \
  NuwaCheckpointCurrentThread2(setjmp(*NuwaCheckpointCurrentThread1()))

/**
 * The following methods are called in the initialization stage of the Nuwa
 * process.
 */

/**
 * Prepare for making the Nuwa process.
 */
MFBT_API void PrepareNuwaProcess();

/**
 * Make the current process a Nuwa process. Start to freeze the threads.
 */
MFBT_API void MakeNuwaProcess();

/**
 * Register a method to be invoked after a new process is spawned. The method
 * will be invoked on the main thread.
 *
 * @param construct The method to be invoked.
 * @param arg The argument passed to the method.
 */
MFBT_API void NuwaAddConstructor(void (*construct)(void *), void *arg);

/**
 * Register a method to be invoked after a new process is spawned and threads
 * are recreated. The method will be invoked on the main thread.
 *
 * @param construct The method to be invoked.
 * @param arg The argument passed to the method.
 */
MFBT_API void NuwaAddFinalConstructor(void (*construct)(void *), void *arg);

/**
 * The methods to query the Nuwa-related states.
 */

/**
 * @return If the current process is the Nuwa process.
 */
MFBT_API bool IsNuwaProcess();

/**
 * @return If the Nuwa process is ready for spawning new processes.
 */
MFBT_API bool IsNuwaReady();
};

#endif /* __NUWA_H_ */