diff options
author | Federico Di Gregorio <fog@initd.org> | 2011-06-13 18:53:48 +0200 |
---|---|---|
committer | Federico Di Gregorio <fog@initd.org> | 2011-06-13 18:53:48 +0200 |
commit | f8ff2ccc49ec32614d42ee852f2fd02fd538e6e5 (patch) | |
tree | ed78b17c013837ac9caac16ee23cdc3dcf5a4042 /scripts/ticket58.py | |
parent | ab685c2fc0a04651041957af7419a1ecfeeb9e53 (diff) | |
parent | f8a5dabdc11364237003f76adadffcd239521138 (diff) | |
download | psycopg2-2_4_2.tar.gz |
Merge branch 'devel'2_4_2
Diffstat (limited to 'scripts/ticket58.py')
-rw-r--r-- | scripts/ticket58.py | 75 |
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() + + |