-
Notifications
You must be signed in to change notification settings - Fork 78
libuv based event loop / server #681
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 17 commits
b33908f
0adb618
7ec1dce
71cf45c
6526c65
f167fdb
f1290dc
ca0b1fd
b94c546
e4241b3
edad43f
8c685c6
3de5865
c7be18d
44f8a31
8a7cc27
0a8469f
3f93c9b
9a3468b
9dd02a4
565eb44
8924b65
1d5b863
1b69129
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /*************************************************************************** | ||
| * Copyright (c) 2018, Martin Renou, Johan Mabille, Sylvain Corlay, and * | ||
| * Wolf Vollprecht * | ||
| * Copyright (c) 2018, QuantStack | ||
| * * | ||
| * Distributed under the terms of the BSD 3-Clause License. * | ||
| * * | ||
| * The full license is in the file LICENSE, distributed with this software. * | ||
| ****************************************************************************/ | ||
|
|
||
| #ifndef XPYT_HOOK_HPP | ||
| #define XPYT_HOOK_HPP | ||
|
|
||
| // pybind11 code internally forces hidden visibility on all internal code, but | ||
| // if non-hidden (and thus exported) code attempts to include a pybind type | ||
| // this warning occurs: | ||
| // 'xpyt::hook' declared with greater visibility than the type of its | ||
| // field 'xpyt::hook::p_acquire' [-Wattributes] | ||
| #ifdef __GNUC__ | ||
| #pragma GCC diagnostic ignored "-Wattributes" | ||
| #endif | ||
|
|
||
| #include "xeus-python/xeus_python_config.hpp" | ||
| #include "xeus-uv/xhook_base.hpp" | ||
|
|
||
| #include "pybind11/embed.h" | ||
| #include "pybind11/pybind11.h" | ||
|
|
||
| namespace py = pybind11; | ||
|
|
||
| namespace xpyt | ||
| { | ||
| XEUS_PYTHON_API | ||
| class hook : public xeus::xhook_base | ||
| { | ||
| public: | ||
|
|
||
| hook() = default; | ||
| virtual ~hook(); | ||
|
|
||
| private: | ||
|
|
||
| void pre_hook_impl() override; | ||
| void post_hook_impl() override; | ||
| void run_impl(std::shared_ptr<uvw::loop> loop) override; | ||
|
|
||
| py::gil_scoped_acquire* p_acquire{ nullptr}; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,14 +21,24 @@ | |
| #include <unistd.h> | ||
| #endif | ||
|
|
||
| #ifndef UVW_AS_LIB | ||
| #define UVW_AS_LIB | ||
| #include <uvw.hpp> | ||
| #endif | ||
|
|
||
| #include "xeus/xkernel.hpp" | ||
| #include "xeus/xkernel_configuration.hpp" | ||
| #include "xeus/xinterpreter.hpp" | ||
| #include "xeus/xhelper.hpp" | ||
|
|
||
| #include "xeus-zmq/xserver_zmq_split.hpp" | ||
| #include "xeus-zmq/xserver_zmq.hpp" | ||
| #include "xeus-zmq/xzmq_context.hpp" | ||
|
|
||
|
|
||
| #include "xeus-uv/xserver_uv.hpp" | ||
| #include "xeus-uv/xhook_base.hpp" | ||
|
|
||
|
|
||
| #include "pybind11/embed.h" | ||
| #include "pybind11/pybind11.h" | ||
|
|
||
|
|
@@ -38,10 +48,10 @@ | |
| #include "xeus-python/xpaths.hpp" | ||
| #include "xeus-python/xeus_python_config.hpp" | ||
| #include "xeus-python/xutils.hpp" | ||
| #include "xeus-python/xhook.hpp" | ||
|
|
||
| namespace py = pybind11; | ||
|
|
||
|
|
||
| int main(int argc, char* argv[]) | ||
| { | ||
| if (xeus::should_print_version(argc, argv)) | ||
|
|
@@ -88,11 +98,35 @@ int main(int argc, char* argv[]) | |
| config.home = const_cast<wchar_t*>(wstr.c_str()); | ||
| xpyt::print_pythonhome(); | ||
|
|
||
| // Implicitly pre-initialize Python | ||
| status = PyConfig_SetBytesArgv(&config, argc, argv); | ||
| if (PyStatus_Exception(status)) { | ||
| std::cerr << "Error:" << status.err_msg << std::endl; | ||
| // Instantiating the Python interpreter | ||
| py::scoped_interpreter guard{}; | ||
|
|
||
| uv_loop_t* uv_loop_ptr{ nullptr }; | ||
|
|
||
| { | ||
| py::gil_scoped_acquire acquire; | ||
|
|
||
| // Create a uvloop and get pointer to the loop | ||
| py::module asyncio = py::module::import("asyncio"); | ||
| py::module uvloop = py::module::import("uvloop"); | ||
| py::object loop = uvloop.attr("new_event_loop")(); | ||
| asyncio.attr("set_event_loop")(loop); | ||
| py::object py_loop_ptr = uvloop.attr("loop").attr("libuv_get_loop_t_ptr")(loop); | ||
|
|
||
| void* raw_ptr = PyCapsule_GetPointer(py_loop_ptr.ptr(), nullptr); | ||
| if (!raw_ptr) | ||
| { | ||
| throw std::runtime_error("Failed to get uvloop pointer"); | ||
| } | ||
|
|
||
| uv_loop_ptr = static_cast<uv_loop_t*>(raw_ptr); | ||
| } | ||
|
|
||
| if (!uv_loop_ptr) | ||
| { | ||
| throw std::runtime_error("Failed to get libuv loop pointer"); | ||
| } | ||
| auto loop_ptr = uvw::loop::create(uv_loop_ptr); | ||
|
|
||
| // Setting argv | ||
| wchar_t** argw = new wchar_t*[size_t(argc)]; | ||
|
|
@@ -113,8 +147,7 @@ int main(int argc, char* argv[]) | |
| } | ||
| delete[] argw; | ||
|
|
||
| // Instantiating the Python interpreter | ||
| py::scoped_interpreter guard; | ||
|
|
||
|
|
||
| std::unique_ptr<xeus::xcontext> context = xeus::make_zmq_context(); | ||
|
|
||
|
|
@@ -146,6 +179,16 @@ int main(int argc, char* argv[]) | |
| nl::json debugger_config; | ||
| debugger_config["python"] = executable; | ||
|
|
||
| auto py_hook = std::make_unique<xpyt::hook>(); | ||
|
|
||
|
|
||
|
|
||
| auto make_xserver = [&](xeus::xcontext& context, | ||
| const xeus::xconfiguration& config, | ||
| nl::json::error_handler_t eh) { | ||
| return xeus::make_xserver_uv(context, config, eh, loop_ptr, std::move(py_hook)); | ||
| }; | ||
|
|
||
| if (!connection_filename.empty()) | ||
| { | ||
| xeus::xconfiguration config = xeus::load_configuration(connection_filename); | ||
|
|
@@ -154,12 +197,12 @@ int main(int argc, char* argv[]) | |
| xeus::get_user_name(), | ||
| std::move(context), | ||
| std::move(interpreter), | ||
| xeus::make_xserver_shell_main, | ||
| make_xserver, | ||
| std::move(hist), | ||
| xeus::make_console_logger(xeus::xlogger::msg_type, | ||
| xeus::make_file_logger(xeus::xlogger::content, "xeus.log")), | ||
| xpyt::make_python_debugger, | ||
| debugger_config); | ||
| xeus::make_file_logger(xeus::xlogger::content, "xeus.log"))); | ||
| // xpyt::make_python_debugger, | ||
| // debugger_config); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that a leftover or does the integration of libuv break the debugger?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. atm this is just the result of merging #620 with the most recent changes / to make it build again. So I assume the debugger stuff was not yet tried |
||
|
|
||
| std::clog << | ||
| "Starting xeus-python kernel...\n\n" | ||
|
|
@@ -175,7 +218,7 @@ int main(int argc, char* argv[]) | |
| xeus::xkernel kernel(xeus::get_user_name(), | ||
| std::move(context), | ||
| std::move(interpreter), | ||
| xeus::make_xserver_shell_main, | ||
| make_xserver, | ||
| std::move(hist), | ||
| nullptr, | ||
| xpyt::make_python_debugger, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| /*************************************************************************** | ||
| * Copyright (c) 2018, Martin Renou, Johan Mabille, Sylvain Corlay, and * | ||
| * Wolf Vollprecht * | ||
| * Copyright (c) 2018, QuantStack | ||
| * * | ||
| * Distributed under the terms of the BSD 3-Clause License. * | ||
| * * | ||
| * The full license is in the file LICENSE, distributed with this software. * | ||
| ****************************************************************************/ | ||
|
|
||
| #ifndef UVW_AS_LIB | ||
| #define UVW_AS_LIB | ||
| #include <uvw.hpp> | ||
| #endif | ||
|
|
||
| #include "xeus-python/xhook.hpp" | ||
|
|
||
| #include "pybind11/embed.h" | ||
| #include "pybind11/pybind11.h" | ||
|
|
||
| namespace py = pybind11; | ||
|
|
||
| namespace xpyt | ||
| { | ||
| hook::~hook() | ||
| { | ||
| delete p_acquire; | ||
| } | ||
|
|
||
| void hook::pre_hook_impl() | ||
| { | ||
| if (!p_acquire) | ||
| { | ||
| p_acquire = new py::gil_scoped_acquire(); | ||
| } | ||
| } | ||
|
|
||
| void hook::post_hook_impl() | ||
| { | ||
| delete p_acquire; | ||
| p_acquire = nullptr; | ||
| } | ||
|
|
||
| void hook::run_impl(std::shared_ptr<uvw::loop> /* loop */) | ||
| { | ||
| py::gil_scoped_acquire acquire; | ||
| py::module asyncio = py::module::import("asyncio"); | ||
| py::object loop = asyncio.attr("get_event_loop")(); | ||
| loop.attr("run_forever")(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking: This could be moved in a dedicated function.