Skip to content

Commit 9ff5f57

Browse files
committed
fix(event-loop): pm.wait attached a different event-loop
File "/home/runner/.cache/pypoetry/virtualenvs/pythonmonkey-lO6uHdZK-py3.9/lib/python3.9/site-packages/pythonmonkey/cli/pmjs.py", line 363, in runJS await pm.wait() # blocks until all asynchronous calls finish File "/opt/hostedtoolcache/Python/3.9.17/x64/lib/python3.9/asyncio/locks.py", line 226, in wait await fut RuntimeError: Task <Task pending name='Task-1' coro=<main.<locals>.runJS() running at /home/runner/.cache/pypoetry/virtualenvs/pythonmonkey-lO6uHdZK-py3.9/lib/python3.9/site-packages/pythonmonkey/cli/pmjs.py:363> cb=[_run_until_complete_cb() at /opt/hostedtoolcache/Python/3.9.17/x64/lib/python3.9/asyncio/base_events.py:184]> got Future <Future pending> attached to a different loop
1 parent c6bf140 commit 9ff5f57

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

include/PyEventLoop.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,9 @@ public:
222222
};
223223

224224
static inline PyEventLoop::Lock *_locker;
225-
protected:
226-
PyObject *_loop;
227225

226+
PyObject *_loop;
227+
protected:
228228
PyEventLoop() = delete;
229229
PyEventLoop(PyObject *loop) : _loop(loop) {};
230230
private:

src/modules/pythonmonkey/pythonmonkey.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ static PyObject *eval(PyObject *self, PyObject *args) {
268268
}
269269
}
270270

271+
static PyObject *waitForEventLoop(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(_)) {
272+
PyObject *waiter = PyEventLoop::_locker->_queueIsEmpty; // instance of asyncio.Event
273+
274+
// Making sure it's attached to the current event-loop
275+
PyEventLoop loop = PyEventLoop::getRunningLoop();
276+
if (!loop.initialized()) return NULL;
277+
PyObject_SetAttrString(waiter, "_loop", loop._loop);
278+
279+
return PyObject_CallMethod(waiter, "wait", NULL);
280+
}
281+
271282
static PyObject *isCompilableUnit(PyObject *self, PyObject *args) {
272283
StrType *buffer = new StrType(PyTuple_GetItem(args, 0));
273284
const char *bufferUtf8;
@@ -289,6 +300,7 @@ static PyObject *isCompilableUnit(PyObject *self, PyObject *args) {
289300

290301
PyMethodDef PythonMonkeyMethods[] = {
291302
{"eval", eval, METH_VARARGS, "Javascript evaluator in Python"},
303+
{"wait", waitForEventLoop, METH_NOARGS, "The event-loop shield. Blocks until all asynchronous jobs finish."},
292304
{"isCompilableUnit", isCompilableUnit, METH_VARARGS, "Hint if a string might be compilable Javascript"},
293305
{"collect", collect, METH_VARARGS, "Calls the spidermonkey garbage collector"},
294306
{NULL, NULL, 0, NULL}
@@ -406,12 +418,6 @@ PyMODINIT_FUNC PyInit_pythonmonkey(void)
406418

407419
// Initialize event-loop shield
408420
PyEventLoop::_locker = new PyEventLoop::Lock();
409-
PyObject *waiter = PyObject_GetAttrString(PyEventLoop::_locker->_queueIsEmpty /* instance of asyncio.Event*/, "wait");
410-
if (!waiter || PyModule_AddObject(pyModule, "wait", waiter) < 0) {
411-
Py_XDECREF(waiter);
412-
Py_DECREF(pyModule);
413-
return NULL;
414-
}
415421

416422
PyObject *internalBindingPy = getInternalBindingPyFn(GLOBAL_CX);
417423
if (PyModule_AddObject(pyModule, "internalBinding", internalBindingPy) < 0) {

0 commit comments

Comments
 (0)