|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set sw=2 ts=2 autoindent cindent expandtab: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef __NUWA_H_ |
|
8 #define __NUWA_H_ |
|
9 |
|
10 #include <setjmp.h> |
|
11 #include <unistd.h> |
|
12 |
|
13 #include "mozilla/Types.h" |
|
14 |
|
15 /** |
|
16 * Nuwa is a goddess who created mankind according to her figure in the |
|
17 * ancient Chinese mythology. |
|
18 */ |
|
19 |
|
20 // Max number of top level protocol that can be handled by Nuwa process. |
|
21 #ifndef NUWA_TOPLEVEL_MAX |
|
22 #define NUWA_TOPLEVEL_MAX 8 |
|
23 #endif |
|
24 |
|
25 struct NuwaProtoFdInfo { |
|
26 int protoId; |
|
27 int originFd; |
|
28 int newFds[2]; |
|
29 }; |
|
30 |
|
31 #define NUWA_NEWFD_PARENT 0 |
|
32 #define NUWA_NEWFD_CHILD 1 |
|
33 |
|
34 extern "C" { |
|
35 |
|
36 /** |
|
37 * The following 3 methods are used to synchronously spawn the Nuwa process. |
|
38 * The typical usage is: |
|
39 * |
|
40 * The IPC thread The main thread |
|
41 * 1. Receives the request. |
|
42 * 2. NuwaSpawnPrepare(). |
|
43 * 3. Request main thread to |
|
44 * spawn. --------------------------------------+ |
|
45 * 4. NuwaSpawnWait(). V |
|
46 * 5. NuwaSpawn() to clone all |
|
47 * the threads in the Nuwa |
|
48 * process (including main |
|
49 * & IPC threads). |
|
50 * 6. NuwaSpawn() finishes and |
|
51 * +-------------------------------------- signals NuwaSpawnWait(). |
|
52 * V |
|
53 * 7. NuwaSpawnWait() returns. |
|
54 */ |
|
55 |
|
56 /** |
|
57 * Prepare for spawning a new process. The calling thread (typically the IPC |
|
58 * thread) will block further requests to spawn a new process. |
|
59 */ |
|
60 MFBT_API void NuwaSpawnPrepare(); |
|
61 |
|
62 /** |
|
63 * Called on the thread that receives the request. Used to wait until |
|
64 * NuwaSpawn() finishes and maintain the stack of the calling thread. |
|
65 */ |
|
66 MFBT_API void NuwaSpawnWait(); |
|
67 |
|
68 /** |
|
69 * Spawn a new content process, called in the Nuwa process. This has to run on |
|
70 * the main thread. |
|
71 * |
|
72 * @return The process ID of the new process. |
|
73 */ |
|
74 MFBT_API pid_t NuwaSpawn(); |
|
75 |
|
76 /** |
|
77 * The following methods are for marking threads created in the Nuwa process so |
|
78 * they can be frozen and then recreated in the spawned process. All threads |
|
79 * except the main thread must be marked by one of the following 4 methods; |
|
80 * otherwise, we have a thread that is created but unknown to us. The Nuwa |
|
81 * process will never become ready and this needs to be fixed. |
|
82 */ |
|
83 |
|
84 /** |
|
85 * Mark the current thread as supporting Nuwa. The thread will implicitly freeze |
|
86 * by calling a blocking method such as pthread_mutex_lock() or epoll_wait(). |
|
87 * |
|
88 * @param recreate The custom function that will be called in the spawned |
|
89 * process, after the thread is recreated. Can be nullptr if no |
|
90 * custom function to be called after the thread is recreated. |
|
91 * @param arg The argument passed to the custom function. Can be nullptr. |
|
92 */ |
|
93 MFBT_API void NuwaMarkCurrentThread(void (*recreate)(void *), void *arg); |
|
94 |
|
95 /** |
|
96 * Mark the current thread as not supporting Nuwa. The calling thread will not |
|
97 * be automatically cloned from the Nuwa process to spawned process. If this |
|
98 * thread needs to be created in the spawned process, use NuwaAddConstructor() |
|
99 * or NuwaAddFinalConstructor() to do it. |
|
100 */ |
|
101 MFBT_API void NuwaSkipCurrentThread(); |
|
102 |
|
103 /** |
|
104 * Force the current thread to freeze explicitly at the current point. |
|
105 */ |
|
106 MFBT_API void NuwaFreezeCurrentThread(); |
|
107 |
|
108 /** |
|
109 * Helper functions for the NuwaCheckpointCurrentThread() macro. |
|
110 */ |
|
111 MFBT_API jmp_buf* NuwaCheckpointCurrentThread1(); |
|
112 |
|
113 MFBT_API bool NuwaCheckpointCurrentThread2(int setjmpCond); |
|
114 |
|
115 /** |
|
116 * Set the point to recover after thread recreation. The calling thread is not |
|
117 * blocked. This is used for the thread that cannot freeze (i.e. the IPC |
|
118 * thread). |
|
119 */ |
|
120 #define NuwaCheckpointCurrentThread() \ |
|
121 NuwaCheckpointCurrentThread2(setjmp(*NuwaCheckpointCurrentThread1())) |
|
122 |
|
123 /** |
|
124 * The following methods are called in the initialization stage of the Nuwa |
|
125 * process. |
|
126 */ |
|
127 |
|
128 /** |
|
129 * Prepare for making the Nuwa process. |
|
130 */ |
|
131 MFBT_API void PrepareNuwaProcess(); |
|
132 |
|
133 /** |
|
134 * Make the current process a Nuwa process. Start to freeze the threads. |
|
135 */ |
|
136 MFBT_API void MakeNuwaProcess(); |
|
137 |
|
138 /** |
|
139 * Register a method to be invoked after a new process is spawned. The method |
|
140 * will be invoked on the main thread. |
|
141 * |
|
142 * @param construct The method to be invoked. |
|
143 * @param arg The argument passed to the method. |
|
144 */ |
|
145 MFBT_API void NuwaAddConstructor(void (*construct)(void *), void *arg); |
|
146 |
|
147 /** |
|
148 * Register a method to be invoked after a new process is spawned and threads |
|
149 * are recreated. The method will be invoked on the main thread. |
|
150 * |
|
151 * @param construct The method to be invoked. |
|
152 * @param arg The argument passed to the method. |
|
153 */ |
|
154 MFBT_API void NuwaAddFinalConstructor(void (*construct)(void *), void *arg); |
|
155 |
|
156 /** |
|
157 * The methods to query the Nuwa-related states. |
|
158 */ |
|
159 |
|
160 /** |
|
161 * @return If the current process is the Nuwa process. |
|
162 */ |
|
163 MFBT_API bool IsNuwaProcess(); |
|
164 |
|
165 /** |
|
166 * @return If the Nuwa process is ready for spawning new processes. |
|
167 */ |
|
168 MFBT_API bool IsNuwaReady(); |
|
169 }; |
|
170 |
|
171 #endif /* __NUWA_H_ */ |