summaryrefslogtreecommitdiff
path: root/sandbox/trigger_double_dealloc.py
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-15 00:58:32 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-15 00:58:32 +0100
commitb205764fdde4549c48c27841aa17e6c7f499e808 (patch)
tree1475eb57dc854ea4a1dc93c1c6a567e6fc584e5c /sandbox/trigger_double_dealloc.py
parente7227ce87b8da75fef1a3376ebb47e2bf20f6063 (diff)
parent7a5edff6c66a0410d6fecd4445980aabafc3ab4a (diff)
downloadpsycopg2-errors-module.tar.gz
Merge branch 'master' into errors-moduleerrors-module
Diffstat (limited to 'sandbox/trigger_double_dealloc.py')
-rw-r--r--sandbox/trigger_double_dealloc.py63
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()