Author: rfm
Date: Fri Mar 11 19:11:43 2016
New Revision: 39531

URL: http://svn.gna.org/viewcvs/gnustep?rev=39531&view=rev
Log:
experimental in-process locking of the distributed locking methods

Modified:
    libs/base/trunk/Source/NSUserDefaults.m

Modified: libs/base/trunk/Source/NSUserDefaults.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSUserDefaults.m?rev=39531&r1=39530&r2=39531&view=diff
==============================================================================
--- libs/base/trunk/Source/NSUserDefaults.m     (original)
+++ libs/base/trunk/Source/NSUserDefaults.m     Fri Mar 11 19:11:43 2016
@@ -91,6 +91,7 @@
 static NSDictionary     *argumentsDictionary = nil;
 static NSMutableString *processName = nil;
 static NSRecursiveLock *classLock = nil;
+static NSLock          *lockLock = nil;
 
 /* Flag to say whether the sharedDefaults variable has been set up by a
  * call to the +standardUserDefaults method.  If this is YES but the variable
@@ -552,6 +553,7 @@
   DESTROY(processName);
   DESTROY(argumentsDictionary);
   DESTROY(classLock);
+  DESTROY(lockLock);
 }
 
 + (void) initialize
@@ -635,6 +637,10 @@
        * so once it exists we know we can used them safely.
        */
       classLock = [NSRecursiveLock new];
+
+      /* This lock protects locking the defaults file.
+       */
+      lockLock = [NSLock new];
 
       [self _createArgumentDictionary: args];
       DESTROY(pool);
@@ -2388,52 +2394,63 @@
 static BOOL isLocked = NO;
 - (BOOL) _lockDefaultsFile: (BOOL*)wasLocked
 {
-  *wasLocked = isLocked;
-  if (isLocked == NO && _fileLock != nil)
-    {
-      NSDate   *started = [NSDateClass date];
-
-      while ([_fileLock tryLock] == NO)
-       {
-         NSAutoreleasePool     *arp = [NSAutoreleasePool new];
-         NSDate                *when;
-         NSDate                *lockDate;
-
-         lockDate = [_fileLock lockDate];
-         when = [NSDateClass dateWithTimeIntervalSinceNow: 0.1];
-
-         /*
-          * In case we have tried and failed to break the lock,
-          * we give up after a while ... 16 seconds should give
-          * us three lock breaks if we do them at 5 second
-          * intervals.
-          */
-         if ([when timeIntervalSinceDate: started] > 16.0)
-           {
-             NSLog(@"Failed to lock user defaults database even after "
-               @"breaking old locks!");
-             [arp drain];
-             return NO;
-           }
-
-         /*
-          * If lockDate is nil, we should be able to lock again ... but we
-          * wait a little anyway ... so that in the case of a locking
-          * problem we do an idle wait rather than a busy one.
-          */
-         if (lockDate != nil && [when timeIntervalSinceDate: lockDate] > 5.0)
-           {
-             [_fileLock breakLock];
-           }
-         else
-           {
-             [NSThread sleepUntilDate: when];
-           }
-         [arp drain];
-       }
-      isLocked = YES;
-    }
-   return YES;
+  [lockLock lock];
+  NS_DURING
+    {
+      *wasLocked = isLocked;
+      if (NO == isLocked && _fileLock != nil)
+        {
+          NSDate       *started = [NSDateClass date];
+
+          while ([_fileLock tryLock] == NO)
+            {
+              NSAutoreleasePool        *arp = [NSAutoreleasePool new];
+              NSDate           *when;
+              NSDate           *lockDate;
+
+              lockDate = [_fileLock lockDate];
+              when = [NSDateClass dateWithTimeIntervalSinceNow: 0.1];
+
+              /*
+               * In case we have tried and failed to break the lock,
+               * we give up after a while ... 16 seconds should give
+               * us three lock breaks if we do them at 5 second
+               * intervals.
+               */
+              if ([when timeIntervalSinceDate: started] > 16.0)
+                {
+                  fprintf(stderr, "Failed to lock user defaults database even 
after "
+                    "breaking old locks!\n");
+                  [arp drain];
+                  break;
+                }
+
+              /*
+               * If lockDate is nil, we should be able to lock again ... but we
+               * wait a little anyway ... so that in the case of a locking
+               * problem we do an idle wait rather than a busy one.
+               */
+              if (lockDate != nil && [when timeIntervalSinceDate: lockDate] > 
5.0)
+                {
+                  [_fileLock breakLock];
+                }
+              else
+                {
+                  [NSThread sleepUntilDate: when];
+                }
+              [arp drain];
+            }
+          isLocked = YES;
+        }
+      [lockLock unlock];
+    }
+  NS_HANDLER
+    {
+      [lockLock unlock];
+      [localException raise];
+    }
+  NS_ENDHANDLER
+  return isLocked;
 }
 
 - (BOOL) _readDefaults
@@ -2503,18 +2520,23 @@
 
 - (void) _unlockDefaultsFile
 {
+  [lockLock lock];
   NS_DURING
     {
-      [_fileLock unlock];
+      if (YES == isLocked)
+        {  
+          [_fileLock unlock];
+        }
     }
   NS_HANDLER
     {
-      NSLog(@"Warning ... someone broke our lock (%@) ... and may have"
-        @" interfered with updating defaults data in file.",
-        lockPath(_defaultsDatabase, NO));
+      fprintf(stderr, "Warning ... someone broke our lock (%s) ... and may 
have"
+        " interfered with updating defaults data in file.",
+        [lockPath(_defaultsDatabase, NO) UTF8String]);
     }
   NS_ENDHANDLER
   isLocked = NO;
+  [lockLock unlock];
 }
 
 @end


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

Reply via email to