Created
July 25, 2023 06:43
-
-
Save pranavsharma/21524ed737ca0b57949a96eaf1fa607d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Author: Pranav Sharma | |
#include <pybind11/pybind11.h> | |
#include <pybind11/functional.h> | |
#include <thread> | |
#include <iostream> | |
#include <chrono> | |
#include <mutex> | |
#include <queue> | |
#define STRINGIFY(x) #x | |
#define MACRO_STRINGIFY(x) STRINGIFY(x) | |
namespace py = pybind11; | |
#include <pybind11/pybind11.h> | |
using PyCallback = std::function<void()>; | |
using CppCallback = std::function<void(void*)>; | |
struct ThreadPool { | |
std::mutex m; | |
std::queue<std::function<void(void)>> q; | |
std::thread t; | |
void Schedule(std::function<void(void)> f) { | |
std::lock_guard<std::mutex> l(m); | |
q.push(f); | |
} | |
~ThreadPool() { | |
t.join(); | |
} | |
ThreadPool() { | |
t = std::thread([this](){ | |
while (true) { | |
std::function<void(void)> f; | |
{ | |
std::lock_guard<std::mutex> l(m); | |
if (!q.empty()) { | |
f = q.front(); | |
q.pop(); | |
} | |
} | |
if (f) { | |
f(); | |
} | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
} | |
}); | |
} | |
}; | |
ThreadPool* tp = nullptr; | |
struct UserData { | |
PyCallback py_callback; | |
}; | |
void Callback(void* user_data) { | |
std::cout << "Inside CPP callback\n"; | |
UserData* user_data_holder = reinterpret_cast<UserData*>(user_data); | |
PyGILState_STATE gstate; | |
gstate = PyGILState_Ensure(); | |
user_data_holder->py_callback(); | |
PyGILState_Release(gstate); | |
} | |
void RunAsync(CppCallback cpp_callback, void* user_data) { | |
tp->Schedule([=]()->void | |
{ | |
std::cout << "Inside thread..sleeping\n"; | |
std::this_thread::sleep_for(std::chrono::milliseconds(10)); | |
std::cout << "Inside thread...done sleeping, calling cpp callback\n"; | |
if (cpp_callback) { | |
cpp_callback(user_data); | |
} | |
}); | |
} | |
PYBIND11_MODULE(test_python_callback, m) { | |
m.def("init", [](){ | |
tp = new ThreadPool(); | |
}); | |
m.def("run_async", [](PyCallback py_callback)->void{ | |
auto user_data_holder = new UserData(); | |
user_data_holder->py_callback = py_callback; | |
{ | |
//py::gil_scoped_release release; | |
RunAsync(Callback, user_data_holder); | |
} | |
}); | |
#ifdef VERSION_INFO | |
m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO); | |
#else | |
m.attr("__version__") = "dev"; | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment