From b3db7a30c0c248616945926e1692e0601d0bbec6 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Thu, 14 Nov 2019 17:48:48 +0300 Subject: Python: optimized response object close() calling. PyObject_HasAttrString() is just a wrapper over PyObject_GetAttrString(), while PyObject_CallMethod() calls it as the first step. As a result, PyObject_GetAttrString() was called twice if close() was present. To get rid of PyObject_HasAttrString() while keeping the same behaviour, the PyObject_CallMethod() call has been decomposed into separate calls of PyObject_GetAttrString() and PyObject_CallFunction(). --- src/nxt_python_wsgi.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c index 54892580..d861a50a 100644 --- a/src/nxt_python_wsgi.c +++ b/src/nxt_python_wsgi.c @@ -370,7 +370,8 @@ static void nxt_python_request_handler(nxt_unit_request_info_t *req) { int rc; - PyObject *environ, *args, *response, *iterator, *item, *result; + PyObject *environ, *args, *response, *iterator, *item; + PyObject *close, *result; nxt_python_run_ctx_t run_ctx = {-1, 0, NULL, req}; PyEval_RestoreThread(nxt_python_thread_state); @@ -461,17 +462,23 @@ nxt_python_request_handler(nxt_unit_request_info_t *req) rc = NXT_UNIT_ERROR; } - if (PyObject_HasAttrString(response, "close")) { - result = PyObject_CallMethod(response, (char *) "close", NULL); + close = PyObject_GetAttrString(response, "close"); - if (nxt_fast_path(result != NULL)) { - Py_DECREF(result); - - } else { + if (close != NULL) { + result = PyObject_CallFunction(close, NULL); + if (nxt_slow_path(result == NULL)) { nxt_unit_req_error(req, "Python failed to call the close() " "method of the application response"); PyErr_Print(); + + } else { + Py_DECREF(result); } + + Py_DECREF(close); + + } else { + PyErr_Clear(); } } -- cgit