This file is indexed.

/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_