summaryrefslogtreecommitdiff
path: root/scripts/ticket58.py
diff options
context:
space:
mode:
authorFederico Di Gregorio <fog@initd.org>2011-06-13 18:53:48 +0200
committerFederico Di Gregorio <fog@initd.org>2011-06-13 18:53:48 +0200
commitf8ff2ccc49ec32614d42ee852f2fd02fd538e6e5 (patch)
treeed78b17c013837ac9caac16ee23cdc3dcf5a4042 /scripts/ticket58.py
parentab685c2fc0a04651041957af7419a1ecfeeb9e53 (diff)
parentf8a5dabdc11364237003f76adadffcd239521138 (diff)
downloadpsycopg2-2_4_2.tar.gz
Merge branch 'devel'2_4_2
Diffstat (limited to 'scripts/ticket58.py')
-rw-r--r--scripts/ticket58.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/scripts/ticket58.py b/scripts/ticket58.py
new file mode 100644
index 0000000..95520c1
--- /dev/null
+++ b/scripts/ticket58.py
@@ -0,0 +1,75 @@
+"""
+A script to reproduce the race condition described in ticket #58
+
+from https://bugzilla.redhat.com/show_bug.cgi?id=711095
+
+Results in the error:
+
+ python: Modules/gcmodule.c:277: visit_decref: Assertion `gc->gc.gc_refs != 0'
+ failed.
+
+on unpatched library.
+"""
+
+import threading
+import gc
+import time
+
+import psycopg2
+from StringIO import StringIO
+
+done = 0
+
+class GCThread(threading.Thread):
+ # A thread that sits in an infinite loop, forcing the garbage collector
+ # to run
+ def run(self):
+ global done
+ while not done:
+ gc.collect()
+ time.sleep(0.1) # give the other thread a chance to run
+
+gc_thread = GCThread()
+
+
+# This assumes a pre-existing db named "test", with:
+# "CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);"
+
+conn = psycopg2.connect("dbname=test user=postgres")
+cur = conn.cursor()
+
+# Start the other thread, running the GC regularly
+gc_thread.start()
+
+# Now do lots of "cursor.copy_from" calls:
+print "copy_from"
+for i in range(1000):
+ f = StringIO("42\tfoo\n74\tbar\n")
+ cur.copy_from(f, 'test', columns=('num', 'data'))
+ # Assuming the other thread gets a chance to run during this call, expect a
+ # build of python (with assertions enabled) to bail out here with:
+ # python: Modules/gcmodule.c:277: visit_decref: Assertion `gc->gc.gc_refs != 0' failed.
+
+# Also exercise the copy_to code path
+print "copy_to"
+cur.execute("truncate test")
+f = StringIO("42\tfoo\n74\tbar\n")
+cur.copy_from(f, 'test', columns=('num', 'data'))
+for i in range(1000):
+ f = StringIO()
+ cur.copy_to(f, 'test', columns=('num', 'data'))
+
+# And copy_expert too
+print "copy_expert"
+cur.execute("truncate test")
+for i in range(1000):
+ f = StringIO("42\tfoo\n74\tbar\n")
+ cur.copy_expert("copy test to stdout", f)
+
+# Terminate the GC thread's loop:
+done = 1
+
+cur.close()
+conn.close()
+
+