/usr/include/hphp/util/async-func.h is in hhvm-dev 3.11.1+dfsg-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | /*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CONCURRENCY_ASYNC_FUNC_H_
#define incl_HPHP_CONCURRENCY_ASYNC_FUNC_H_
#include <pthread.h>
#include <folly/Portability.h>
#include "hphp/util/synchronizable.h"
#include "hphp/util/lock.h"
#include "hphp/util/exception.h"
#include "hphp/util/alloc.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
/**
* Invokes a function asynchrously. For example,
*
* class MyClass {
* public:
* void doJob();
* };
*
* MyClass obj;
* AsyncFunc<MyClass> func(&obj, &MyClasss::doJob);
* func.start(); // this will call obj.doJob() in a separate thread
* // do something else
* func.waitForEnd();
*
* Asynchronous function is a slightly different way of thinking about threads.
* Maybe this can help people understand asynchronous function is actually a
* broader/identical view of running threads,
*
* class MyRunnable {
* public:
* void run();
* };
*
* MyRunnable thread;
* AsyncFunc<Runnable> func(&thread, &MyRunnable::run);
* thread.run();
*
* Well, asynchronous function is sometimes more flexible in writing a server,
* because it can bind different threads to methods on the same object:
*
* class MyServer {
* public:
* void thread1();
* void thread2();
* };
*
* MyServer server;
* AsyncFunc<MyServer> func1(&server, &MyServer::thread1);
* AsyncFunc<MyServer> func2(&server, &MyServer::thread2);
* func1.start();
* func2.start();
* ...now both threads are running, accessing the same server object.
*
* There is nothing wrong embedding the async function object itself in the
* class like this,
*
* class MyServer {
* public:
* MyServer()
* : m_thread1(this, &MyServer::thread1),
* : m_thread2(this, &MyServer::thread2) {
* }
*
* void thread1();
* void thread2();
*
* void start() {
* m_thread1.start();
* m_thread2.start();
* }
*
* private:
* AsyncFunc<MyServer> m_thread1;
* AsyncFunc<MyServer> m_thread2;
* };
*
*/
struct AsyncFuncImpl {
typedef void PFN_THREAD_FUNC(void *);
static const size_t kStackSizeMinimum =
#ifdef FOLLY_SANITIZE_ADDRESS
// asan modifies the generated code in ways that cause abnormally high C++
// stack usage.
16 << 20;
#else
8 << 20;
#endif
/**
* The global static to feed into pthread_create(), and this will delegate
* the work to AsyncFuncImpl::threadFuncImpl().
*/
static void *ThreadFunc(void *obj);
/**
* Called by AsyncFunc<T> so we can call func(obj) back on thread running.
*/
AsyncFuncImpl(void *obj, PFN_THREAD_FUNC *func);
~AsyncFuncImpl();
/**
* Starts this thread.
*/
void start();
/**
* Sends a cancellation request to the thread. NB: Do not use this unless
* the function is known to support cancellation and known to leave shared
* state in a consistent state (alternatively, the caller should proceed to
* shut down the process as well). Also, call waitForEnd following this call
* before proceeding as if the async func has stopped executing.
*/
void cancel();
/**
* Waits until this thread finishes running.
*/
bool waitForEnd(int seconds = 0);
/**
* Starts and waits until this thread finishes running.
*/
void run() {
start();
waitForEnd();
}
pthread_attr_t *getThreadAttr() {
return &m_attr;
}
static void SetThreadInitFunc(PFN_THREAD_FUNC* func, void *arg) {
s_initFunc = func;
s_initFuncArg = arg;
}
static void SetThreadFiniFunc(PFN_THREAD_FUNC* func, void *arg) {
s_finiFunc = func;
s_finiFuncArg = arg;
}
static PFN_THREAD_FUNC* GetThreadInitFunc() {
return s_initFunc;
}
static PFN_THREAD_FUNC* GetThreadFiniFunc() {
return s_finiFunc;
}
void setNoInit() { m_noInit = true; }
private:
Synchronizable m_stopMonitor;
void* m_obj;
PFN_THREAD_FUNC* m_func;
static PFN_THREAD_FUNC* s_initFunc;
static PFN_THREAD_FUNC* s_finiFunc;
static void* s_initFuncArg;
static void* s_finiFuncArg;
void* m_threadStack;
pthread_attr_t m_attr;
pthread_t m_threadId;
Exception* m_exception; // exception was thrown and thread was terminated
int m_node;
bool m_stopped;
bool m_noInit;
/**
* Called by ThreadFunc() to delegate the work.
*/
void threadFuncImpl();
};
///////////////////////////////////////////////////////////////////////////////
/**
* We could have written AysncFunc<T> directly with those methods implemented
* inside AsyncFuncImpl class, but this way we reduce sizes of our code by
* only templatizing a very minimal piece of code, sharing everything inside
* AsyncFuncImpl by all AsyncFunc<T> classes.
*/
template<class T>
class AsyncFunc : public AsyncFuncImpl {
public:
AsyncFunc(T *obj, void (T::*member_func)())
: AsyncFuncImpl((void*)this, run_), m_obj(obj), m_memberFunc(member_func) {
}
static void run_(void *obj) {
AsyncFunc<T> *p = (AsyncFunc<T>*)obj;
(p->m_obj->*(p->m_memberFunc))();
}
private:
T *m_obj;
void (T::*m_memberFunc)();
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CONCURRENCY_ASYNC_FUNC_H_
|