summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2019-11-14 17:48:48 +0300
committerValentin Bartenev <vbart@nginx.com>2019-11-14 17:48:48 +0300
commitb3db7a30c0c248616945926e1692e0601d0bbec6 (patch)
treedf3415350976af983d0ea32d363917c7c9071262
parent75c2c23bb6cd95a9e08d89f74e6457321d266ed2 (diff)
downloadunit-b3db7a30c0c248616945926e1692e0601d0bbec6.tar.gz
unit-b3db7a30c0c248616945926e1692e0601d0bbec6.tar.bz2
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().
-rw-r--r--src/nxt_python_wsgi.c21
1 files changed, 14 insertions, 7 deletions
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();
}
}