Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / init-fini-node.h
blob5491691376a1e078d68d063bc0c126297c39e80b
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_THREAD_INIT_FINI_H_
18 #define incl_HPHP_THREAD_INIT_FINI_H_
20 #include "hphp/util/portability.h"
21 #include "hphp/util/assertions.h"
22 #include "hphp/util/async-job.h"
24 namespace HPHP {
25 ///////////////////////////////////////////////////////////////////////////////
27 struct InitFiniNode;
29 struct IFJob {
30 explicit IFJob(const InitFiniNode& n) : node(n) {}
31 const InitFiniNode& node;
33 template <> struct WorkerInfo<IFJob> {
34 enum { DoInitFini = false };
37 struct InitFiniNode {
38 enum class When {
39 RequestStart, // before executing PHP code in a request
40 RequestFini,
41 ThreadInit,
42 ThreadFini,
43 // ProcessInitConcurrent should only be used for thread-safe code with few
44 // dependencies (e.g., runtime options, logging).
45 PostRuntimeOptions, // after runtime options are set, single-threaded
46 ProcessPreInit, // after pthread initialization and config parsing
47 ProcessInit, // after PreInit
48 ProcessInitConcurrent, // after PreInit, concurrently with Init and others
49 ProcessExit, // after Init and InitConcurrent
50 ServerPreInit,
51 ServerInit,
52 WarmupConcurrent, // concurrent with OS file cache warmup, optional
53 ServerExit,
54 GlobalsInit,
56 Sentinel
59 const static unsigned NumNodes = static_cast<unsigned>(When::Sentinel);
61 InitFiniNode(void(*f)(), When when, const char* what = nullptr) {
62 InitFiniNode*& n = node(when);
63 func = f;
64 next = n;
65 name = what;
66 n = this;
69 static void RequestStart() { iterate(When::RequestStart); }
70 static void RequestFini() { iterate(When::RequestFini); }
71 static void ThreadInit() { iterate(When::ThreadInit); }
72 static void ThreadFini() { iterate(When::ThreadFini); }
73 static void ProcessPostRuntimeOptions() {
74 iterate(When::PostRuntimeOptions);
76 static void ProcessPreInit() { iterate(When::ProcessPreInit); }
77 static void ProcessInit() { iterate(When::ProcessInit); }
78 // Use maxWorkers == 0 to run synchronously on current thread.
79 static void ProcessInitConcurrentStart(uint32_t maxWorkers);
80 static void ProcessInitConcurrentWaitForEnd();
81 static void ProcessFini() { iterate(When::ProcessExit); }
82 static void ServerPreInit() { iterate(When::ServerPreInit); }
83 static void ServerInit() { iterate(When::ServerInit); }
84 static void WarmupConcurrentStart(uint32_t maxWorkers);
85 static void WarmupConcurrentWaitForEnd(); // No-op if not started.
86 static void ServerFini() { iterate(When::ServerExit); }
87 static void GlobalsInit() { iterate(When::GlobalsInit); }
89 struct IFWorker {
90 void onThreadEnter() {}
91 void doJob(std::shared_ptr<IFJob> job);
92 void onThreadExit() {}
94 private:
95 using IFDispatcher = JobDispatcher<IFJob, IFWorker>;
97 static InitFiniNode*& node(When when) {
98 auto idx = static_cast<unsigned>(when);
99 assert(idx < NumNodes);
100 return s_nodes[idx];
102 static IFDispatcher*& dispatcher(When when) {
103 auto idx = static_cast<unsigned>(when);
104 assert(idx < NumNodes);
105 return s_dispatcher[idx];
107 void (*func)();
108 InitFiniNode* next;
109 const char* name;
111 static void iterate(When when) { iterate(node(when)); }
112 static void iterate(InitFiniNode* node);
113 static void concurrentStart(uint32_t maxWorkers, When when);
114 static void concurrentWaitForEnd(When when);
116 static InitFiniNode* s_nodes[NumNodes];
117 static IFDispatcher* s_dispatcher[NumNodes];
120 ///////////////////////////////////////////////////////////////////////////////
123 #endif // incl_HPHP_THREAD_INIT_FINI_H_