2 +----------------------------------------------------------------------+
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"
25 ///////////////////////////////////////////////////////////////////////////////
30 explicit IFJob(const InitFiniNode
& n
) : node(n
) {}
31 const InitFiniNode
& node
;
33 template <> struct WorkerInfo
<IFJob
> {
34 enum { DoInitFini
= false };
39 RequestStart
, // before executing PHP code in a request
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
52 WarmupConcurrent
, // concurrent with OS file cache warmup, optional
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
);
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
); }
90 void onThreadEnter() {}
91 void doJob(std::shared_ptr
<IFJob
> job
);
92 void onThreadExit() {}
95 using IFDispatcher
= JobDispatcher
<IFJob
, IFWorker
>;
97 static InitFiniNode
*& node(When when
) {
98 auto idx
= static_cast<unsigned>(when
);
99 assert(idx
< NumNodes
);
102 static IFDispatcher
*& dispatcher(When when
) {
103 auto idx
= static_cast<unsigned>(when
);
104 assert(idx
< NumNodes
);
105 return s_dispatcher
[idx
];
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_