bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #46956] Thread safety issues in NSUserDefaults.m cause unwarranted


From: Larry Campbell
Subject: [bug #46956] Thread safety issues in NSUserDefaults.m cause unwarranted exceptions to be raised
Date: Sat, 23 Jan 2016 21:19:52 +0000
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9

URL:
  <http://savannah.gnu.org/bugs/?46956>

                 Summary: Thread safety issues in NSUserDefaults.m cause
unwarranted exceptions to be raised
                 Project: GNUstep
            Submitted by: lcampbel
            Submitted on: Sat 23 Jan 2016 09:19:50 PM GMT
                Category: Base/Foundation
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

The fix for bug #40620 has caused a new problem. Since
_createArgumentsDictionary can now return nil, this can cause this snippet of
initWithContentsOfFile:

  [_tempDomains setObject: [self _createArgumentDictionary]
                   forKey: NSArgumentDomain];

to raise an exception:

Tried to add nil value for key 'NSArgumentDomain' to dictionary

Since this code can be called implicitly when you call something, like NSLog,
that you don't really expect ever to raise exceptions, this can cause
problems. (In my case, a lock was left locked, because I really didn't expect
to have to catch exceptions from NSLog, and this caused a deadlock later on.)

The following code snippet easily reproduces the problem:

- (void)cr3283311_thread0:(NSDate *)deadline
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    const NSTimeInterval sleepTime = 0.01;
    unsigned frobs = 0;
    const NSTimeInterval blagInterval = 2.0;
    NSDate *nextBlag = [[NSDate dateWithTimeIntervalSinceNow:blagInterval]
retain];
    
    NSLog(@"cr3283311_thread0 starting");
    while ([deadline timeIntervalSinceNow] > 0.0) {
        NSAutoreleasePool *pool = [NSAutoreleasePool new];
        [[NSUserDefaults standardUserDefaults] setBool:YES
forKey:@"freddieboy"];
        [NSUserDefaults resetStandardUserDefaults];
        [NSThread sleepForTimeInterval:sleepTime];
        [[NSUserDefaults standardUserDefaults] setBool:YES
forKey:@"freddieboy"];
        [NSUserDefaults resetStandardUserDefaults];
        [NSThread sleepForTimeInterval:sleepTime];
        frobs++;
        if ([nextBlag timeIntervalSinceNow] < 0.0) {
            NSTimeInterval t = -[deadline timeIntervalSinceNow];
            NSLog(@"  Time remaining: %.1f sec; frobs: %u", t, frobs);
            [nextBlag release];
            nextBlag = [[NSDate dateWithTimeIntervalSinceNow:blagInterval]
retain];
        }
        [pool release];
    }
    [nextBlag release];
    NSLog(@"cr3283311_thread0 ending");
    [pool release];
}

- (void)cr3283311_threadn:(NSDate *)deadline
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    const NSTimeInterval sleepTime = 0.01;
    NSUInteger counts = 0;
    unsigned trips = 0;

    NSLog(@"cr3283311_threadn starting");
    while ([deadline timeIntervalSinceNow] > 0.0) {
        NSAutoreleasePool *pool = [NSAutoreleasePool new];
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        NSDictionary *d;
        
        NSAssert(ud != nil, @"NSUserDefaults botch");
        d = [ud dictionaryRepresentation];
        counts += [d count];
        trips++;
        [NSThread sleepForTimeInterval:sleepTime];
        [pool release];
    }
    NSLog(@"cr3283311_threadn ending");
    [pool release];
}

- (void)cr3283311
{
    const unsigned threadCount = 4;
    unsigned i;
    const NSTimeInterval runningTime = 60.0;
    NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:runningTime];

    [NSThread detachNewThreadSelector:@selector(cr3283311_thread0:)
toTarget:self withObject:deadline];
    for (i = 0; i < threadCount; i++)
        [NSThread detachNewThreadSelector:@selector(cr3283311_threadn:)
toTarget:self withObject:deadline];

    while ([deadline timeIntervalSinceNow] > 0.0)
        [NSThread sleepForTimeInterval:0.1];
}





    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?46956>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]