Skip to content
This repository has been archived by the owner on Apr 9, 2023. It is now read-only.

Commit

Permalink
Fix memory leak in get_current_request (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
vangheem committed May 4, 2017
1 parent a4e1618 commit a3cd471
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/plone.server/CHANGELOG.rst
@@ -1,6 +1,9 @@
1.0a16 (unreleased)
-------------------

- Fix memory leak in get_current_request
[vangheem]

- Be able to provide `aiohttp_settings` in config.json to configure parts of
aiohttp application
[vangheem]
Expand Down
11 changes: 7 additions & 4 deletions src/plone.server/plone/server/optimizations.c
Expand Up @@ -17,6 +17,8 @@ current_request()
if (PyFrame_FastToLocalsWithError(f) < 0)
return NULL;

Py_INCREF(f->f_locals);

if (PyDict_CheckExact(f->f_locals)) {
self = PyDict_GetItem(f->f_locals, PyUnicode_FromString("self"));

Expand All @@ -25,14 +27,16 @@ current_request()
if (PyObject_HasAttr(self, PyUnicode_FromString("request"))) {
found = 1;
request = PyObject_GetAttr(self, PyUnicode_FromString("request"));
}
}
if (PyObject_IsInstance(self, RequestHandler)) {
found = 1;
request = PyDict_GetItem(f->f_locals, PyUnicode_FromString("request"));
Py_INCREF(request);
}
}

}

Py_DECCREF(f->f_locals);
f = f->f_back;
}

Expand All @@ -43,7 +47,6 @@ current_request()
return NULL;
}

Py_INCREF(request);
return (PyObject*)request;
}

Expand Down Expand Up @@ -95,4 +98,4 @@ PyInit_optimizations(void)
Py_DECREF(m);

return ob;
}
}
25 changes: 25 additions & 0 deletions src/plone.server/plone/server/tests/test_utils.py
@@ -1,8 +1,33 @@
from plone.server import utils
from plone.server.testing import FakeRequest
from plone.server.transactions import get_current_request

import gc
import resource


def test_module_resolve_path():
assert utils.resolve_module_path('plone.server') == 'plone.server'
assert utils.resolve_module_path('plone.server.tests') == 'plone.server.tests'
assert utils.resolve_module_path('..test_queue') == 'plone.server.tests.test_queue'
assert utils.resolve_module_path('....api') == 'plone.server.api'


class TestGetCurrentRequest:
def test_gcr_memory(self):
self.request = FakeRequest()

count = 0
current = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024.0 / 1024.0
while True:
count += 1
get_current_request()

if count % 1000000 == 0:
break

if count % 100000 == 0:
gc.collect()
new = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024.0 / 1024.0
if new - current > 10: # memory leak, this shouldn't happen
assert new == current

0 comments on commit a3cd471

Please sign in to comment.