1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-12 09:29:55 +01:00
Telegram/thirdparty/GDFileManager/GDParentOperation.m
2015-10-01 19:19:52 +03:00

162 lines
3.8 KiB
Objective-C
Executable File

//
// GDParentOperation.m
//
//
// Created by Graham Dennis on 6/07/13.
//
//
#import "GDParentOperation.h"
@interface GDParentOperation ()
@property (nonatomic) dispatch_queue_t private_queue;
@property (nonatomic, assign) BOOL isExecuting;
@property (nonatomic, assign) BOOL isFinished;
@property (nonatomic, strong) NSMutableArray *childOperations;
@end
NSError *GDOperationCancelledError;
@implementation GDParentOperation
@synthesize successCallbackQueue = _successCallbackQueue;
@synthesize failureCallbackQueue = _failureCallbackQueue;
+ (void)initialize
{
if (self == [GDParentOperation class]) {
GDOperationCancelledError = [NSError errorWithDomain:@"GDParentOperation" code:0 userInfo:nil];
}
}
#if !OS_OBJECT_USE_OBJC
- (void)dealloc
{
if (self.private_queue) {
dispatch_release(self.private_queue);
self.private_queue = NULL;
}
if (_successCallbackQueue) {
dispatch_release(_successCallbackQueue);
_successCallbackQueue = NULL;
}
if (_failureCallbackQueue) {
dispatch_release(_failureCallbackQueue);
_failureCallbackQueue = NULL;
}
}
#endif
- (id)init
{
if ((self = [super init])) {
self.private_queue = dispatch_queue_create("me.grahamdennis.GDParentOperation", DISPATCH_QUEUE_SERIAL);
self.childOperations = [NSMutableArray new];
}
return self;
}
- (void)start
{
dispatch_sync(self.private_queue, ^{
if ([self isCancelled]) {
[self willChangeValueForKey:@"isFinished"];
self.isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
}
else if ([self isReady] && ![self isExecuting]) {
[self willChangeValueForKey:@"isExecuting"];
self.isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self main];
});
}
});
}
- (void)main {}
- (void)finish
{
dispatch_sync(self.private_queue, ^{
if ([self isExecuting]) {
[self willChangeValueForKey:@"isExecuting"];
self.isExecuting = NO;
[self didChangeValueForKey:@"isExecuting"];
}
[self willChangeValueForKey:@"isFinished"];
self.isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
});
}
- (void)cancel
{
dispatch_sync(self.private_queue, ^{
[super cancel];
for (NSOperation *childOperation in self.childOperations) {
[childOperation cancel];
}
});
}
- (BOOL)isConcurrent { return YES; }
- (void)addChildOperation:(NSOperation *)operation
{
if (!operation) return;
dispatch_async(self.private_queue, ^{
if ([self isCancelled]) {
[operation cancel];
}
[self.childOperations addObject:operation];
});
}
#if !OS_OBJECT_USE_OBJC
- (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue
{
dispatch_retain(successCallbackQueue);
if (_successCallbackQueue) {
dispatch_release(_successCallbackQueue);
}
_successCallbackQueue = successCallbackQueue;
}
#endif
- (dispatch_queue_t)successCallbackQueue
{
if (!_successCallbackQueue)
return dispatch_get_main_queue();
return _successCallbackQueue;
}
#if !OS_OBJECT_USE_OBJC
- (void)setFailureCallbackQueue:(dispatch_queue_t)failureCallbackQueue
{
dispatch_retain(failureCallbackQueue);
if (_failureCallbackQueue) {
dispatch_release(_failureCallbackQueue);
}
_failureCallbackQueue = failureCallbackQueue;
}
#endif
- (dispatch_queue_t)failureCallbackQueue
{
if (!_failureCallbackQueue)
return dispatch_get_main_queue();
return _failureCallbackQueue;
}
@end