proxygen
GILAwareManualExecutor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <Python.h>
20 
21 #include <folly/ScopeGuard.h>
22 
23 namespace folly {
24 namespace python {
25 
27  {
28  std::lock_guard<std::mutex> lock(lock_);
29  funcs_.emplace(std::move(callback));
30  }
31  cv_.notify_one();
32 }
33 
35  std::unique_lock<std::mutex> lock(lock_);
36  if (!funcs_.empty()) {
37  return;
38  }
39 
40  // Release GIL before waiting on lock
41  auto* pyThreadState = PyEval_SaveThread();
42  SCOPE_EXIT {
43  // Release lock before re-acquiring GIL,
44  // to avoid deadlock if another GIL-owning thread is calling add
45  lock.unlock();
46  PyEval_RestoreThread(pyThreadState);
47  };
48  cv_.wait(lock, [&] { return !funcs_.empty(); });
49 }
50 
52  Func func;
53  while (true) {
54  {
55  std::lock_guard<std::mutex> lock(lock_);
56  if (funcs_.empty()) {
57  break;
58  }
59 
60  func = std::move(funcs_.front());
61  funcs_.pop();
62  }
63  func();
64  }
65 }
66 
67 } // namespace python
68 } // namespace folly
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
auto lock(Synchronized< D, M > &synchronized, Args &&...args)