mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 03:16:10 +00:00
IPyKernel signal and poll
This commit is contained in:
parent
926a9ffd1e
commit
693fc1eb1f
@ -7,8 +7,8 @@ from ipykernel.ipkernel import IPythonKernel
|
||||
|
||||
# TODO: Make this behave like a Popen instance and pipe it to IPyKernelInterfaceJupyter!
|
||||
class IPyKernelInterfaceKernel:
|
||||
def kill(self):
|
||||
print("No!! Not into the pit! It burns!!!")
|
||||
def send_signal(self, signum):
|
||||
pass
|
||||
|
||||
def poll(self):
|
||||
return None
|
||||
|
@ -1,34 +1,32 @@
|
||||
|
||||
from jupyter_client.ioloop import IOLoopKernelManager
|
||||
from notebook.notebookapp import *
|
||||
import signal
|
||||
import cutter_internal
|
||||
|
||||
|
||||
# TODO: this must behave like a Popen instance and pipe to IPyKernelInterfaceKernel!
|
||||
class IPyKernelInterfaceJupyter:
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
|
||||
def send_signal(self, signum):
|
||||
cutter_internal.kernel_interface_send_signal(self._id, signum)
|
||||
|
||||
def kill(self):
|
||||
print("DIE!! " + str(self._id))
|
||||
self.send_signal(signal.SIGKILL)
|
||||
|
||||
def terminate(self):
|
||||
self.send_signal(signal.SIGTERM)
|
||||
|
||||
def poll(self):
|
||||
return None
|
||||
return cutter_internal.kernel_interface_poll(self._id)
|
||||
|
||||
def wait(self, timeout=None):
|
||||
pass
|
||||
|
||||
|
||||
class CutterInternalIPyKernelManager(IOLoopKernelManager):
|
||||
def start_kernel(self, **kw):
|
||||
"""Starts a kernel on this host in a separate process.
|
||||
|
||||
If random ports (port=0) are being used, this method must be called
|
||||
before the channels are created.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
`**kw` : optional
|
||||
keyword arguments that are passed down to build the kernel_cmd
|
||||
and launching the kernel (e.g. Popen kwargs).
|
||||
"""
|
||||
|
||||
# write connection file / get default ports
|
||||
self.write_connection_file()
|
||||
|
||||
@ -50,15 +48,16 @@ class CutterInternalIPyKernelManager(IOLoopKernelManager):
|
||||
self.log.debug("Starting kernel: %s", kernel_cmd)
|
||||
|
||||
# TODO: kernel_cmd including python executable and so on is currently used for argv. Make a clean version!
|
||||
import cutter_internal
|
||||
id = cutter_internal.launch_ipykernel(kernel_cmd, env=env, **kw)
|
||||
self.kernel = IPyKernelInterfaceJupyter(id)
|
||||
# self._launch_kernel(kernel_cmd, env=env,
|
||||
# **kw)
|
||||
# self._launch_kernel(kernel_cmd, env=env, **kw)
|
||||
|
||||
self.start_restarter()
|
||||
self._connect_control_socket()
|
||||
|
||||
def signal_kernel(self, signum):
|
||||
self.kernel.send_signal(signum)
|
||||
|
||||
|
||||
def kernel_manager_factory(kernel_name, **kwargs):
|
||||
if kernel_name in {"python", "python2", "python3"}:
|
||||
|
@ -144,5 +144,10 @@ long JupyterConnection::startNestedIPyKernel(const QStringList &argv)
|
||||
|
||||
NestedIPyKernel *JupyterConnection::getNestedIPyKernel(long id)
|
||||
{
|
||||
return kernels[id];
|
||||
auto it = kernels.find(id);
|
||||
if(it == kernels.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return *it;
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ NestedIPyKernel *NestedIPyKernel::start(const QStringList &argv)
|
||||
|
||||
NestedIPyKernel::NestedIPyKernel(PyObject *cutterIPykernelModule, const QStringList &argv)
|
||||
{
|
||||
threadState = PyThreadState_Get();
|
||||
|
||||
auto launchFunc = PyObject_GetAttrString(cutterIPykernelModule, "launch_ipykernel");
|
||||
|
||||
PyObject *argvListObject = PyList_New(argv.size());
|
||||
@ -59,12 +61,24 @@ NestedIPyKernel::NestedIPyKernel(PyObject *cutterIPykernelModule, const QStringL
|
||||
|
||||
NestedIPyKernel::~NestedIPyKernel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NestedIPyKernel::kill()
|
||||
void NestedIPyKernel::sendSignal(long signum)
|
||||
{
|
||||
auto parentThreadState = PyThreadState_Swap(threadState);
|
||||
PyObject_CallMethod(kernel, "kill", nullptr);
|
||||
PyObject_CallMethod(kernel, "send_signal", "l", signum);
|
||||
PyThreadState_Swap(parentThreadState);
|
||||
}
|
||||
|
||||
QVariant NestedIPyKernel::poll()
|
||||
{
|
||||
QVariant ret;
|
||||
auto parentThreadState = PyThreadState_Swap(threadState);
|
||||
PyObject *pyRet = PyObject_CallMethod(kernel, "poll", nullptr);
|
||||
if(PyLong_Check(pyRet))
|
||||
{
|
||||
ret = (qlonglong)PyLong_AsLong(pyRet);
|
||||
}
|
||||
PyThreadState_Swap(parentThreadState);
|
||||
return ret;
|
||||
}
|
@ -17,7 +17,8 @@ public:
|
||||
static NestedIPyKernel *start(const QStringList &argv);
|
||||
~NestedIPyKernel();
|
||||
|
||||
void kill();
|
||||
void sendSignal(long signum);
|
||||
QVariant poll();
|
||||
|
||||
private:
|
||||
NestedIPyKernel(PyObject *cutterIPykernelModule, const QStringList &argv);
|
||||
|
@ -74,25 +74,60 @@ PyObject *api_internal_launch_ipykernel(PyObject *self, PyObject *args, PyObject
|
||||
return PyLong_FromLong(id);
|
||||
}
|
||||
|
||||
PyObject *api_internal_kernel_interface_kill(PyObject *, PyObject *args)
|
||||
PyObject *api_internal_kernel_interface_send_signal(PyObject *, PyObject *args)
|
||||
{
|
||||
long id;
|
||||
long signum;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ll", &id, &signum))
|
||||
{
|
||||
qWarning() << "Invalid args passed to api_internal_kernel_interface_send_signal().";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NestedIPyKernel *kernel = Jupyter()->getNestedIPyKernel(id);
|
||||
if(kernel)
|
||||
{
|
||||
kernel->sendSignal(signum);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *api_internal_kernel_interface_poll(PyObject *, PyObject *args)
|
||||
{
|
||||
long id;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l", &id))
|
||||
{
|
||||
qWarning() << "Invalid args passed to api_internal_kernel_interface_kill().";
|
||||
qWarning() << "Invalid args passed to api_internal_kernel_interface_poll().";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Jupyter()->getNestedIPyKernel(id)->kill();
|
||||
NestedIPyKernel *kernel = Jupyter()->getNestedIPyKernel(id);
|
||||
if(!kernel)
|
||||
{
|
||||
return PyLong_FromLong(0);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
QVariant v = kernel->poll();
|
||||
bool ok;
|
||||
auto ret = static_cast<long>(v.toLongLong(&ok));
|
||||
if(ok)
|
||||
{
|
||||
return PyLong_FromLong(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
PyMethodDef CutterInternalMethods[] = {
|
||||
{"launch_ipykernel", (PyCFunction)api_internal_launch_ipykernel, METH_VARARGS | METH_KEYWORDS,
|
||||
"Launch an IPython Kernel in a subinterpreter"},
|
||||
{"kernel_interface_kill", (PyCFunction)api_internal_kernel_interface_kill, METH_VARARGS, ""},
|
||||
{"kernel_interface_send_signal", (PyCFunction)api_internal_kernel_interface_send_signal, METH_VARARGS, ""},
|
||||
{"kernel_interface_poll", (PyCFunction)api_internal_kernel_interface_poll, METH_VARARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user