From fb3e9c00ed79f4d880ab9a67aab861eb3660ec75 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 21 Sep 2018 09:11:32 +0300 Subject: bpo-34755: Add few minor optimizations in _asynciomodule.c. (GH-9455) --- Modules/_asynciomodule.c | 274 ++++++++++++++++++++--------------------------- 1 file changed, 116 insertions(+), 158 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2ed033c..fc91ebd 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -10,6 +10,7 @@ module _asyncio /* identifiers used from some functions */ _Py_IDENTIFIER(__asyncio_running_event_loop__); +_Py_IDENTIFIER(_asyncio_future_blocking); _Py_IDENTIFIER(add_done_callback); _Py_IDENTIFIER(_all_tasks_compat); _Py_IDENTIFIER(call_soon); @@ -22,7 +23,6 @@ _Py_IDENTIFIER(throw); /* State of the _asyncio module */ static PyObject *asyncio_mod; -static PyObject *inspect_isgenerator; static PyObject *traceback_extract_stack; static PyObject *asyncio_get_event_loop_policy; static PyObject *asyncio_future_repr_info_func; @@ -1304,13 +1304,8 @@ FutureObj_repr(FutureObj *fut) return NULL; } - PyObject *rstr = NULL; - PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), - "__name__"); - if (type_name != NULL) { - rstr = PyUnicode_FromFormat("<%S %U>", type_name, rinfo_s); - Py_DECREF(type_name); - } + PyObject *rstr = PyUnicode_FromFormat("<%s %U>", + _PyType_Name(Py_TYPE(fut)), rinfo_s); Py_DECREF(rinfo_s); return rstr; } @@ -1326,7 +1321,6 @@ FutureObj_finalize(FutureObj *fut) PyObject *error_type, *error_value, *error_traceback; PyObject *context; - PyObject *type_name; PyObject *message = NULL; PyObject *func; @@ -1344,14 +1338,8 @@ FutureObj_finalize(FutureObj *fut) goto finally; } - type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__"); - if (type_name == NULL) { - goto finally; - } - message = PyUnicode_FromFormat( - "%S exception was never retrieved", type_name); - Py_DECREF(type_name); + "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut))); if (message == NULL) { goto finally; } @@ -1543,7 +1531,7 @@ static PyObject * FutureIter_send(futureiterobject *self, PyObject *unused) { /* Future.__iter__ doesn't care about values that are pushed to the - * generator, it just returns "self.result(). + * generator, it just returns self.result(). */ return FutureIter_iternext(self); } @@ -2702,163 +2690,142 @@ set_exception: goto different_loop; } - if (fut->fut_blocking) { - fut->fut_blocking = 0; + if (!fut->fut_blocking) { + goto yield_insteadof_yf; + } - /* result.add_done_callback(task._wakeup) */ - wrapper = TaskWakeupMethWrapper_new(task); - if (wrapper == NULL) { - goto fail; - } - res = future_add_done_callback( - (FutureObj*)result, wrapper, task->task_context); - Py_DECREF(wrapper); - if (res == NULL) { - goto fail; - } - Py_DECREF(res); + fut->fut_blocking = 0; - /* task._fut_waiter = result */ - task->task_fut_waiter = result; /* no incref is necessary */ + /* result.add_done_callback(task._wakeup) */ + wrapper = TaskWakeupMethWrapper_new(task); + if (wrapper == NULL) { + goto fail; + } + res = future_add_done_callback( + (FutureObj*)result, wrapper, task->task_context); + Py_DECREF(wrapper); + if (res == NULL) { + goto fail; + } + Py_DECREF(res); - if (task->task_must_cancel) { - PyObject *r; - r = future_cancel(fut); - if (r == NULL) { - return NULL; - } - if (r == Py_True) { - task->task_must_cancel = 0; - } - Py_DECREF(r); - } + /* task._fut_waiter = result */ + task->task_fut_waiter = result; /* no incref is necessary */ - Py_RETURN_NONE; + if (task->task_must_cancel) { + PyObject *r; + r = future_cancel(fut); + if (r == NULL) { + return NULL; + } + if (r == Py_True) { + task->task_must_cancel = 0; + } + Py_DECREF(r); } - else { - goto yield_insteadof_yf; + + Py_RETURN_NONE; + } + + /* Check if `result` is None */ + if (result == Py_None) { + /* Bare yield relinquishes control for one event loop iteration. */ + if (task_call_step_soon(task, NULL)) { + goto fail; } + return result; } /* Check if `result` is a Future-compatible object */ - o = PyObject_GetAttrString(result, "_asyncio_future_blocking"); - if (o == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); + if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) { + goto fail; + } + if (o != NULL && o != Py_None) { + /* `result` is a Future-compatible object */ + PyObject *wrapper; + PyObject *res; + + int blocking = PyObject_IsTrue(o); + Py_DECREF(o); + if (blocking < 0) { + goto fail; } - else { + + /* Check if `result` future is attached to a different loop */ + PyObject *oloop = get_future_loop(result); + if (oloop == NULL) { goto fail; } - } - else { - if (o == Py_None) { - Py_DECREF(o); + if (oloop != task->task_loop) { + Py_DECREF(oloop); + goto different_loop; } - else { - /* `result` is a Future-compatible object */ - PyObject *wrapper; - PyObject *res; + Py_DECREF(oloop); - int blocking = PyObject_IsTrue(o); - Py_DECREF(o); - if (blocking < 0) { - goto fail; - } + if (!blocking) { + goto yield_insteadof_yf; + } - /* Check if `result` future is attached to a different loop */ - PyObject *oloop = get_future_loop(result); - if (oloop == NULL) { - goto fail; - } - if (oloop != task->task_loop) { - Py_DECREF(oloop); - goto different_loop; - } - else { - Py_DECREF(oloop); - } + /* result._asyncio_future_blocking = False */ + if (_PyObject_SetAttrId( + result, &PyId__asyncio_future_blocking, Py_False) == -1) { + goto fail; + } - if (blocking) { - /* result._asyncio_future_blocking = False */ - if (PyObject_SetAttrString( - result, "_asyncio_future_blocking", Py_False) == -1) { - goto fail; - } + wrapper = TaskWakeupMethWrapper_new(task); + if (wrapper == NULL) { + goto fail; + } - wrapper = TaskWakeupMethWrapper_new(task); - if (wrapper == NULL) { - goto fail; - } + /* result.add_done_callback(task._wakeup) */ + PyObject *add_cb = _PyObject_GetAttrId( + result, &PyId_add_done_callback); + if (add_cb == NULL) { + Py_DECREF(wrapper); + goto fail; + } + PyObject *stack[2]; + stack[0] = wrapper; + stack[1] = (PyObject *)task->task_context; + res = _PyObject_FastCallKeywords( + add_cb, stack, 1, context_kwname); + Py_DECREF(add_cb); + Py_DECREF(wrapper); + if (res == NULL) { + goto fail; + } + Py_DECREF(res); - /* result.add_done_callback(task._wakeup) */ - PyObject *add_cb = _PyObject_GetAttrId( - result, &PyId_add_done_callback); - if (add_cb == NULL) { - Py_DECREF(wrapper); - goto fail; - } - PyObject *stack[2]; - stack[0] = wrapper; - stack[1] = (PyObject *)task->task_context; - res = _PyObject_FastCallKeywords( - add_cb, stack, 1, context_kwname); - Py_DECREF(add_cb); - Py_DECREF(wrapper); - if (res == NULL) { - goto fail; - } - Py_DECREF(res); - - /* task._fut_waiter = result */ - task->task_fut_waiter = result; /* no incref is necessary */ - - if (task->task_must_cancel) { - PyObject *r; - int is_true; - r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); - if (r == NULL) { - return NULL; - } - is_true = PyObject_IsTrue(r); - Py_DECREF(r); - if (is_true < 0) { - return NULL; - } - else if (is_true) { - task->task_must_cancel = 0; - } - } + /* task._fut_waiter = result */ + task->task_fut_waiter = result; /* no incref is necessary */ - Py_RETURN_NONE; + if (task->task_must_cancel) { + PyObject *r; + int is_true; + r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); + if (r == NULL) { + return NULL; } - else { - goto yield_insteadof_yf; + is_true = PyObject_IsTrue(r); + Py_DECREF(r); + if (is_true < 0) { + return NULL; + } + else if (is_true) { + task->task_must_cancel = 0; } } - } - /* Check if `result` is None */ - if (result == Py_None) { - /* Bare yield relinquishes control for one event loop iteration. */ - if (task_call_step_soon(task, NULL)) { - goto fail; - } - return result; + Py_RETURN_NONE; } + Py_XDECREF(o); /* Check if `result` is a generator */ - o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL); - if (o == NULL) { - /* An exception in inspect.isgenerator */ + res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type); + if (res < 0) { goto fail; } - res = PyObject_IsTrue(o); - Py_DECREF(o); - if (res == -1) { - /* An exception while checking if 'val' is True */ - goto fail; - } - if (res == 1) { + if (res) { /* `result` is a generator */ o = task_set_error_soon( task, PyExc_RuntimeError, @@ -2922,7 +2889,7 @@ task_step(TaskObj *task, PyObject *exc) return NULL; } else { - if(leave_task(task->task_loop, (PyObject*)task) < 0) { + if (leave_task(task->task_loop, (PyObject*)task) < 0) { Py_DECREF(res); return NULL; } @@ -3237,7 +3204,6 @@ static void module_free(void *m) { Py_CLEAR(asyncio_mod); - Py_CLEAR(inspect_isgenerator); Py_CLEAR(traceback_extract_stack); Py_CLEAR(asyncio_future_repr_info_func); Py_CLEAR(asyncio_get_event_loop_policy); @@ -3278,15 +3244,10 @@ module_init(void) } - context_kwname = PyTuple_New(1); + context_kwname = Py_BuildValue("(s)", "context"); if (context_kwname == NULL) { goto fail; } - PyObject *context_str = PyUnicode_FromString("context"); - if (context_str == NULL) { - goto fail; - } - PyTuple_SET_ITEM(context_kwname, 0, context_str); #define WITH_MOD(NAME) \ Py_CLEAR(module); \ @@ -3319,9 +3280,6 @@ module_init(void) WITH_MOD("asyncio.coroutines") GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine") - WITH_MOD("inspect") - GET_MOD_ATTR(inspect_isgenerator, "isgenerator") - WITH_MOD("traceback") GET_MOD_ATTR(traceback_extract_stack, "extract_stack") @@ -3388,7 +3346,7 @@ PyInit__asyncio(void) if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { return NULL; } - if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { + if (PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { return NULL; } if (PyType_Ready(&TaskType) < 0) { -- cgit v0.12