mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
Add Cancellable.get_pollfd()
Useful for integrating with an existing event loop.
This commit is contained in:
@@ -448,6 +448,9 @@ class Cancellable(object):
|
||||
def raise_if_cancelled(self):
|
||||
self._impl.raise_if_cancelled()
|
||||
|
||||
def get_pollfd(self):
|
||||
return CancellablePollFD(self._impl)
|
||||
|
||||
@classmethod
|
||||
def get_current(cls):
|
||||
return _Cancellable.get_current()
|
||||
@@ -468,6 +471,30 @@ class Cancellable(object):
|
||||
self._impl.cancel()
|
||||
|
||||
|
||||
class CancellablePollFD(object):
|
||||
def __init__(self, cancellable):
|
||||
self.handle = cancellable.get_fd()
|
||||
self._cancellable = cancellable
|
||||
|
||||
def __del__(self):
|
||||
self.release()
|
||||
|
||||
def release(self):
|
||||
if self._cancellable is not None:
|
||||
self._cancellable.release_fd()
|
||||
self._cancellable = None
|
||||
self.handle = -1
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.handle)
|
||||
|
||||
def __enter__(self):
|
||||
return self.handle
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.release()
|
||||
|
||||
|
||||
def _to_camel_case(name):
|
||||
result = ""
|
||||
uppercase_next = False
|
||||
|
||||
@@ -375,6 +375,8 @@ static int PyCancellable_init (PyCancellable * self, PyObject * args, PyObject *
|
||||
static PyObject * PyCancellable_repr (PyCancellable * self);
|
||||
static PyObject * PyCancellable_is_cancelled (PyCancellable * self);
|
||||
static PyObject * PyCancellable_raise_if_cancelled (PyCancellable * self);
|
||||
static PyObject * PyCancellable_get_fd (PyCancellable * self);
|
||||
static PyObject * PyCancellable_release_fd (PyCancellable * self);
|
||||
static PyObject * PyCancellable_get_current (PyCancellable * self);
|
||||
static PyObject * PyCancellable_push_current (PyCancellable * self);
|
||||
static PyObject * PyCancellable_pop_current (PyCancellable * self);
|
||||
@@ -553,6 +555,8 @@ static PyMethodDef PyCancellable_methods[] =
|
||||
{
|
||||
{ "is_cancelled", (PyCFunction) PyCancellable_is_cancelled, METH_NOARGS, "Query whether cancellable has been cancelled." },
|
||||
{ "raise_if_cancelled", (PyCFunction) PyCancellable_raise_if_cancelled, METH_NOARGS, "Raise an exception if cancelled." },
|
||||
{ "get_fd", (PyCFunction) PyCancellable_get_fd, METH_NOARGS, "Get file descriptor for integrating with an event loop." },
|
||||
{ "release_fd", (PyCFunction) PyCancellable_release_fd, METH_NOARGS, "Release a resource previously allocated by get_fd()." },
|
||||
{ "get_current", (PyCFunction) PyCancellable_get_current, METH_CLASS | METH_NOARGS, "Get the top cancellable from the stack." },
|
||||
{ "push_current", (PyCFunction) PyCancellable_push_current, METH_NOARGS, "Push cancellable onto the cancellable stack." },
|
||||
{ "pop_current", (PyCFunction) PyCancellable_pop_current, METH_NOARGS, "Pop cancellable off the cancellable stack." },
|
||||
@@ -3695,6 +3699,20 @@ PyCancellable_raise_if_cancelled (PyCancellable * self)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCancellable_get_fd (PyCancellable * self)
|
||||
{
|
||||
return PyLong_FromLong (g_cancellable_get_fd (PY_GOBJECT_HANDLE (self)));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCancellable_release_fd (PyCancellable * self)
|
||||
{
|
||||
g_cancellable_release_fd (PY_GOBJECT_HANDLE (self));
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCancellable_get_current (PyCancellable * self)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user