diff options
Diffstat (limited to 'sandbox/trigger_double_dealloc.py')
-rw-r--r-- | sandbox/trigger_double_dealloc.py | 63 |
1 files changed, 0 insertions, 63 deletions
diff --git a/sandbox/trigger_double_dealloc.py b/sandbox/trigger_double_dealloc.py deleted file mode 100644 index 1312aa3..0000000 --- a/sandbox/trigger_double_dealloc.py +++ /dev/null @@ -1,63 +0,0 @@ -from __future__ import print_function - -import psycopg2, psycopg2.extensions -import threading -import gc -import time -import sys - -# inherit psycopg2 connection class just so that -# garbage collector enters the tp_clear code path -# in delete_garbage() - -class my_connection(psycopg2.extensions.connection): - pass - -class db_user(threading.Thread): - def run(self): - conn2 = psycopg2.connect(sys.argv[1], connection_factory=my_connection) - cursor = conn2.cursor() - cursor.execute("UPDATE test_psycopg2_dealloc SET a = 3", async=1) - - # the conn2 desctructor will block indefinitely - # on the completion of the query - # (and it will not be holding the GIL during that time) - print("begin conn2 del", file=sys.stderr) - del cursor, conn2 - print("end conn2 del", file=sys.stderr) - -def main(): - # lock out a db row - conn1 = psycopg2.connect(sys.argv[1], connection_factory=my_connection) - cursor = conn1.cursor() - cursor.execute("DROP TABLE IF EXISTS test_psycopg2_dealloc") - cursor.execute("CREATE TABLE test_psycopg2_dealloc (a int)") - cursor.execute("INSERT INTO test_psycopg2_dealloc VALUES (1)") - conn1.commit() - cursor.execute("UPDATE test_psycopg2_dealloc SET a = 2", async=1) - - # concurrent thread trying to access the locked row - db_user().start() - - # eventually, a gc.collect run will happen - # while the conn2 is inside conn_close() - # but this second dealloc won't get blocked - # as it will avoid conn_close() - for i in range(10): - if gc.collect(): - print("garbage collection done", file=sys.stderr) - break - time.sleep(1) - - # we now unlock the row by invoking - # the desctructor of conn1. This will permit the - # concurrent thread destructor of conn2 to - # continue and it will end up trying to free - # self->dsn a second time. - print("begin conn1 del", file=sys.stderr) - del cursor, conn1 - print("end conn1 del", file=sys.stderr) - - -if __name__ == '__main__': - main() |