mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
202 lines
6.5 KiB
C
202 lines
6.5 KiB
C
/* -*- 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.
|
|
* Note that this function is called duing thread recreation
|
|
* while other threads are frozen. It must not perform any
|
|
* action (e.g. acquiring a mutex) that might depend on another
|
|
* thread that is still blocked.
|
|
* @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 *before* recreating the other threads.
|
|
* The registered method must not perform any action (e.g. acquiring a mutex)
|
|
* that might depend on another thread that has not yet been recreated.
|
|
*
|
|
* @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 *after*
|
|
* the other threads are recreated and fully functional.
|
|
*
|
|
* @param construct The method to be invoked.
|
|
* @param arg The argument passed to the method.
|
|
*/
|
|
MFBT_API void NuwaAddFinalConstructor(void (*construct)(void *), void *arg);
|
|
|
|
|
|
/**
|
|
* Register a method to be invoked after the current thread is recreated in the
|
|
* spawned process. Note that this function is called while other threads are
|
|
* frozen. It must not perform any action (e.g. acquiring a mutex) that might
|
|
* depend on another thread that is still blocked.
|
|
*
|
|
* @param construct The method to be invoked.
|
|
* @param arg The argument passed to the method.
|
|
*/
|
|
MFBT_API void NuwaAddThreadConstructor(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();
|
|
|
|
#if defined(DEBUG) || defined(ENABLE_TESTS)
|
|
/**
|
|
* Asserts that aThread is not frozen.
|
|
*/
|
|
MFBT_API void NuwaAssertNotFrozen(unsigned int aThread,
|
|
const char* aThreadName);
|
|
#else
|
|
#define NuwaAssertNotFrozen(aThread, aThreadName) do {} while(0);
|
|
#endif
|
|
};
|
|
|
|
#endif /* __NUWA_H_ */
|