Commit a1d2f1f7 authored by Julien Phalip's avatar Julien Phalip
Browse files

Ensured that thread-shareability gets validated when closing a PostgreSQL or...

Ensured that thread-shareability gets validated when closing a PostgreSQL or SQLite connection. Refs #17258.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17206 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 34e248ef
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
        self.cursor().execute('SET CONSTRAINTS ALL DEFERRED')

    def close(self):
        self.validate_thread_sharing()
        if self.connection is None:
            return

+1 −0
Original line number Diff line number Diff line
@@ -300,6 +300,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
                        referenced_table_name, referenced_column_name))

    def close(self):
        self.validate_thread_sharing()
        # If database is in memory, closing the connection destroys the
        # database. To prevent accidental data loss, ignore close requests on
        # an in-memory db.
+45 −0
Original line number Diff line number Diff line
@@ -487,6 +487,9 @@ class ThreadTests(TestCase):
        def runner():
            from django.db import connections
            for conn in connections.all():
                # Allow thread sharing so the connection can be closed by the
                # main thread.
                conn.allow_thread_sharing = True
                connections_set.add(conn)
        for x in xrange(2):
            t = threading.Thread(target=runner)
@@ -538,3 +541,45 @@ class ThreadTests(TestCase):
        do_thread()
        # All good
        self.assertEqual(len(exceptions), 0)

    def test_closing_non_shared_connections(self):
        """
        Ensure that a connection that is not explicitly shareable cannot be
        closed by another thread.
        Refs #17258.
        """
        # First, without explicitly enabling the connection for sharing.
        exceptions = set()
        def runner1():
            def runner2(other_thread_connection):
                try:
                    other_thread_connection.close()
                except DatabaseError, e:
                    exceptions.add(e)
            t2 = threading.Thread(target=runner2, args=[connections['default']])
            t2.start()
            t2.join()
        t1 = threading.Thread(target=runner1)
        t1.start()
        t1.join()
        # The exception was raised
        self.assertEqual(len(exceptions), 1)

        # Then, with explicitly enabling the connection for sharing.
        exceptions = set()
        def runner1():
            def runner2(other_thread_connection):
                try:
                    other_thread_connection.close()
                except DatabaseError, e:
                    exceptions.add(e)
            # Enable thread sharing
            connections['default'].allow_thread_sharing = True
            t2 = threading.Thread(target=runner2, args=[connections['default']])
            t2.start()
            t2.join()
        t1 = threading.Thread(target=runner1)
        t1.start()
        t1.join()
        # No exception was raised
        self.assertEqual(len(exceptions), 0)
 No newline at end of file
+1 −1

File changed.

Contains only whitespace changes.