Author: rfm
Date: Tue Jun  9 18:47:36 2015
New Revision: 38606

URL: http://svn.gna.org/viewcvs/gnustep?rev=38606&view=rev
Log:
Attempted deadlock fix

Modified:
    libs/sqlclient/trunk/ChangeLog
    libs/sqlclient/trunk/SQLClient.m

Modified: libs/sqlclient/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/ChangeLog?rev=38606&r1=38605&r2=38606&view=diff
==============================================================================
--- libs/sqlclient/trunk/ChangeLog      (original)
+++ libs/sqlclient/trunk/ChangeLog      Tue Jun  9 18:47:36 2015
@@ -1,3 +1,9 @@
+2015-06-09 Richard Frith-Macdonald  <[email protected]>
+
+       * SQLClient.m: Fix reace condition spotted by Wolfgang and change
+       purge operation to avoid disconnecting clients while the class lock
+       is locked.
+
 2015-05-28 Richard Frith-Macdonald  <[email protected]>
 
        * SQLClient.h: Add pool purge control method.

Modified: libs/sqlclient/trunk/SQLClient.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=38606&r1=38605&r2=38606&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m    (original)
+++ libs/sqlclient/trunk/SQLClient.m    Tue Jun  9 18:47:36 2015
@@ -903,10 +903,15 @@
 + (void) purgeConnections: (NSDate*)since
 {
   NSHashEnumerator     e;
+  NSMutableArray        *a = nil;
   SQLClient            *o;
   unsigned int         connectionCount = 0;
-  NSTimeInterval       t = [since timeIntervalSinceReferenceDate];
-
+  NSTimeInterval       t;
+
+  t = (nil == since) ? 0.0 : [since timeIntervalSinceReferenceDate];
+
+  /* Find clients we may want to disconnect.
+   */
   [clientsLock lock];
   e = NSEnumerateHashTable(clientsHash);
   while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
@@ -915,18 +920,60 @@
        {
          NSTimeInterval        when = o->_lastOperation;
 
+          if (when < o->_lastStart)
+            {
+              when = o->_lastStart;
+            }
          if (when < t && YES == o->connected)
            {
-             [o disconnect];
+              if (nil == a)
+                {
+                  a = [NSMutableArray array];
+                }
+              [a addObject: o];
            }
        }
-      if ([o connected] == YES)
+      else if ([o connected] == YES)
        {
          connectionCount++;
        }
     }
   NSEndHashTableEnumeration(&e);
   [clientsLock unlock];
+
+  /* Disconnect any clients idle too long
+   */
+  while ([a count] > 0)
+    {
+      o = [a lastObject];
+      if ([o->lock tryLock])
+        {
+         NSTimeInterval        when = o->_lastOperation;
+
+          if (when < o->_lastStart)
+            {
+              when = o->_lastStart;
+            }
+         if (when < t && YES == o->connected)
+            {
+              NS_DURING
+                {
+                  [o disconnect];
+                  if ([o connected] == YES)
+                    {
+                      connectionCount++;
+                    }
+                }
+              NS_HANDLER
+                {
+                  NSLog(@"Problem disconnecting: %@", localException);
+                }
+              NS_ENDHANDLER
+            }
+          [o->lock unlock];
+        }
+      [a removeLastObject];
+    }
 
   while (connectionCount >= (maxConnections + poolConnections))
     {
@@ -942,11 +989,15 @@
            {
              NSTimeInterval    when = o->_lastOperation;
 
+              if (when < o->_lastStart)
+                {
+                  when = o->_lastStart;
+                }
              connectionCount++;
              if (oldest == 0.0 || when < oldest)
                {
                  oldest = when;
-                 other = o;
+                 ASSIGN(other, o);
                }
            }
        }
@@ -959,7 +1010,7 @@
            @"Force disconnect of '%@' because max connections (%u) reached",
            other, maxConnections]; 
        }
-      [other disconnect];
+      [AUTORELEASE(other) disconnect];
     }
 }
 


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to