-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.m
95 lines (71 loc) · 2.5 KB
/
main.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
// main.m
// CoordinationDeadlock
//
// Created by Friedrich Gräter on 05.03.14.
// Copyright (c) 2014 Friedrich Gräter. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface SomePresenter : NSObject <NSFilePresenter>
{
NSURL *_URL;
NSOperationQueue *_queue;
}
- (id)initWithURL:(NSURL *)URL;
@end
@implementation SomePresenter
- (id)initWithURL:(NSURL *)URL
{
self = [super init];
if (self) {
_URL = URL;
_queue = [NSOperationQueue new];
_queue.maxConcurrentOperationCount = 1;
[NSFileCoordinator addFilePresenter: self];
}
return self;
}
- (NSURL *)presentedItemURL
{
return _URL;
}
- (NSOperationQueue *)presentedItemOperationQueue
{
return _queue;
}
- (void)presentedItemDidChange
{
NSLog(@"Will read: %@", _URL);
// Deadlock occurs, since both presenters are waiting for the callback of -relinquishPresentedItemToReader of the respective other presenter, which are enqueued after the -presentedItemDidChange.
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateReadingItemAtURL:_URL options:NSFileCoordinatorReadingWithoutChanges error:NULL byAccessor:^(NSURL *newURL) {
NSLog(@"Change presented: %@", newURL);
}];
NSLog(@"Completed.");
}
- (void)relinquishPresentedItemToReader:(void (^)(void (^)(void)))reader
{
// Will never be called, since -presentedItemDidChange is blocking the queue...
NSLog(@"Relinquish read...");
reader(^{ NSLog(@"Relinquished reader"); });
}
@end
int main(int argc, const char * argv[])
{
// Setup presenters
NSURL *tempURL = [[NSURL fileURLWithPath: @"test.txt"] URLByStandardizingPath];
[@"xy" writeToURL:tempURL atomically:YES encoding:NSUTF8StringEncoding error:NULL];
SomePresenter *presenterA = [[SomePresenter alloc] initWithURL: tempURL];
SomePresenter *presenterB = [[SomePresenter alloc] initWithURL: tempURL];
// Generate a -presentedItemDidChange in both presenters by writing the file
[[[NSFileCoordinator alloc] initWithFilePresenter: nil] coordinateWritingItemAtURL:tempURL options:0 error:NULL byAccessor:^(NSURL *newURL) {
[@"abc" writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:NULL];
}];
// Wait some seconds for -presentedItemDidChange notifications to be enqueued
[NSThread sleepForTimeInterval: 2];
// Wait until operations have been completed
NSLog(@"Wait for completion:");
[presenterA.presentedItemOperationQueue waitUntilAllOperationsAreFinished];
[presenterB.presentedItemOperationQueue waitUntilAllOperationsAreFinished];
// Never reached...
NSLog(@"Done.");
}