Message243031
Nick, Guido,
Attached is a patch that fixes a refleak in 'async with' implementation.
The problem is related to WITH_CLEANUP_START/WITH_CLEANUP_FINISH opcodes.
For regular 'with' statements, these opcodes go one after another (essentially, it was one opcode before 'async with').
For 'async with' statements, we have a GET_AWAITABLE/YIELD_FROM pair between them.
Now, if an error occurred during running a GET_AWAITABLE or a YIELD_FROM opcode, WITH_CLEANUP_FINISH was unreachable. All blocks were correctly unwound by the eval loop, but exception object got too many DECREFS.
My solution is to continue using WITH_CLEANUP_START/WITH_CLEANUP_FINISH opcodes, but use SETUP_EXCEPT to guard them and nested YIELD_FROM and GET_AWAITABLE.
In case of an exception, I propose to use another new opcode -- ASYNC_WITH_CLEANUP_EXCEPT. It unwinds the block set up by SETUP_EXCEPT, restores exception, NULLifies a copy of exception in the stack and does 'goto error', letting eval loop do the rest.
"./python.exe -m test -R3:3 test_coroutines" with this patch reports no refleaks. I also updates test_coroutines with a lot of new 'async with' tests, I think that I got all usecases covered.
Please take a look at the patch, I want to commit it as soon as possible. |
|
Date |
User |
Action |
Args |
2015-05-13 03:36:04 | yselivanov | set | recipients:
+ yselivanov, gvanrossum, ncoghlan, scoder, vstinner, asvetlov, python-dev |
2015-05-13 03:36:03 | yselivanov | set | messageid: <1431488163.37.0.65142555224.issue24017@psf.upfronthosting.co.za> |
2015-05-13 03:36:03 | yselivanov | link | issue24017 messages |
2015-05-13 03:36:03 | yselivanov | create | |
|