Revision: 25413
http://sourceforge.net/p/bibdesk/svn/25413
Author: hofman
Date: 2021-01-16 16:12:22 +0000 (Sat, 16 Jan 2021)
Log Message:
-----------
Collapse FVOperation and FVConcreteOperation classes, it was not really used as
a class cluster anyway, and all concrete subclasses were subclasses of
FVConcreteOperation
Modified Paths:
--------------
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVIconOperation.h
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVInvocationOperation.h
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.h
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.m
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m
trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVIconOperation.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVIconOperation.h 2021-01-16
15:40:15 UTC (rev 25412)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVIconOperation.h 2021-01-16
16:12:22 UTC (rev 25413)
@@ -37,11 +37,11 @@
*/
#import <Cocoa/Cocoa.h>
-#import "FVConcreteOperation.h"
+#import "FVOperation.h"
@class FVIcon, FVFileView;
-@interface FVIconOperation : FVConcreteOperation
+@interface FVIconOperation : FVOperation
{
@protected;
FVIcon *_icon;
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVInvocationOperation.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVInvocationOperation.h
2021-01-16 15:40:15 UTC (rev 25412)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVInvocationOperation.h
2021-01-16 16:12:22 UTC (rev 25413)
@@ -37,13 +37,13 @@
*/
#import <Cocoa/Cocoa.h>
-#import "FVConcreteOperation.h"
+#import "FVOperation.h"
#import <libkern/OSAtomic.h>
/** @internal @brief FVOperation subclass wraps NSInvocation
FVInvocationOperation is designed to be similar in usage to
NSInvocationOperation. It can be created with any invocation, but the
invocation should not be modified after the operation has been enqueued.
FVInvocationOperation is capable of returning a value; non-objects are wrapped
in an NSValue. */
-@interface FVInvocationOperation : FVConcreteOperation
+@interface FVInvocationOperation : FVOperation
{
@private;
NSInvocation *_invocation;
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.h 2021-01-16
15:40:15 UTC (rev 25412)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.h 2021-01-16
16:12:22 UTC (rev 25413)
@@ -51,7 +51,7 @@
/** FVOperation abstract class.
- This is an abstract class. A subclass must override FVOperation::main to
actually do work.
+ This is a semi-abstract class. A subclass must override FVOperation::main to
actually do work. FVOperation provides storage for ivars and a default
implementation of all required methods except FVOperation::main, so it's a good
starting point for subclasses. FVOperation is thread safe.
The lifecycle of an operation goes like this:
- owner does [FVOperationSubclass new]
@@ -63,8 +63,15 @@
- FVOperation::finished checks to see if the operation wasn't cancelled, and
calls FVOperationQueue::finishedOperation: with self as the argument
- the queue then releases the operation and it's gone
- The queue maintains a set of active oprations so they can be cancelled even
when running FVOperation::start (which could prevent callbacks from being
invoked in an operation subclass). */
+ The queue maintains a set of active oprations so they can be cancelled even
when running FVOperation::start (which could prevent callbacks from being
invoked in an operation subclass).
+
+ @warning The NSThread detached in a concurrent operation retains the
operation as well as the queue, so the operation could hypothetically outlive
the queue. Hence the operation retains all ivars in order to avoid messaging a
garbage pointer, so you have to cancel or wait until the operation completes in
order for the queue itself to be deallocated. The queue itself handles this in
FVOperationQueue::terminate. */
@interface FVOperation : NSObject
+{
+@private;
+ id _queue;
+ struct FVOpFlags *_flags;
+}
/** Designated initializer. */
- (id)init;
@@ -76,23 +83,17 @@
- (NSUInteger)hash;
/** Equality test.
- Subclasses should override hash and isEqual: for correct coalescing
semantics. Default implementation uses pointer equality.
+ Subclasses may override hash and isEqual: for correct coalescing semantics.
Default implementation uses pointer equality.
@return YES if instances are equal as determined by the implementor. */
- (BOOL)isEqual:(id)object;
-//
-// subclasses must implement all of the following; do not call super
-//
-
/** Sets the FVOperationQueue.
- Required for subclassers. Do not call super.
@param aQueue The queue that will execute this task. */
- (void)setQueue:(id)aQueue;
/** The queue that will execute the task.
- Required for subclassers. Do not call super.
@return An instance of FVOperationQueue or nil. */
- (id)queue;
@@ -102,30 +103,25 @@
/** Priority of this task.
- Required for subclassers. Do not call super.
@return The operation's priority. */
- (FVOperationQueuePriority)queuePriority;
/** Set priority of this task.
- Required for subclassers. Do not call super.
@param queuePriority An integral value from the
FVOperation.h::FVOperationQueuePriority enum. */
- (void)setQueuePriority:(FVOperationQueuePriority)queuePriority;
/** Cancel this task.
-
- Required for subclassers. Do not call super. */
+ */
- (void)cancel;
/** Cancellation status of this task.
- Required for subclassers. Do not call super.
@return YES if FVOperation::cancel was called previously. */
- (BOOL)isCancelled;
/** Whether the task is running.
- Required for subclassers. Do not call super.
@return YES if the task is currently executing. */
- (BOOL)isExecuting;
@@ -141,9 +137,14 @@
The operation queue calls this in order to execute the task, if it has not
previously been cancelled. */
- (void)main;
+/** Check to see if the operation is concurrent.
+
+ This method returns NO by default for consistency with NSOperation.
Subclasses may override this.
+ @return YES if it detaches a new thread in FVOperation::start, NO otherwise.
*/
+- (BOOL)isConcurrent;
+
/** Change concurrency.
- Required for subclassers. Do not call super.
This is not part of the NSOperation API, but it's useful. Raises an
exception if the operation was previously cancelled or executed.
@param flag YES if the operation should detach its own thread to call
FVOperation::main. */
- (void)setConcurrent:(BOOL)flag;
@@ -164,12 +165,6 @@
If FVOperation::isConcurrent returns YES, detaches a thread to call
FVOperation::main. If not concurrent, calls FVOperation::main from whatever
thread called FVOperation::start. Raises if the operation was previously
cancelled or executed. */
- (void)start;
-/** Check to see if the operation is concurrent.
-
- This method returns NO by default for consistency with NSOperation.
Subclasses may override this.
- @return YES if it detaches a new thread in FVOperation::start, NO otherwise.
*/
-- (BOOL)isConcurrent;
-
/** Notification that an operation is finished.
A subclass must call this when FVOperation::main completes in order to avoid
leaking FVOperation instances in the queue. */
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.m 2021-01-16
15:40:15 UTC (rev 25412)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVOperation.m 2021-01-16
16:12:22 UTC (rev 25413)
@@ -37,45 +37,40 @@
*/
#import "FVOperation.h"
-#import "FVConcreteOperation.h"
#import "FVOperationQueue.h"
#import "FVThread.h"
+#import <libkern/OSAtomic.h>
+struct FVOpFlags {
+ volatile int32_t _cancelled;
+ volatile int32_t _priority;
+ volatile int32_t _executing;
+ volatile int32_t _finished;
+ volatile int32_t _concurrent;
+};
-@interface FVPlaceholderOperation : FVOperation
-@end
-
@implementation FVOperation
-// FVOperation abstract class stuff
-static FVOperation *defaultPlaceholderOperation = nil;
-static Class FVOperationClass = Nil;
-
-+ (void)initialize
+- (id)init
{
- FVINITIALIZE(FVOperation);
-
- FVOperationClass = self;
- defaultPlaceholderOperation = (FVOperation
*)NSAllocateObject([FVPlaceholderOperation self], 0, [self zone]);
+ self = [super init];
+ if (self) {
+ _queue = nil;
+ _flags = NSZoneCalloc([self zone], 1, sizeof(struct FVOpFlags));
+
+ // set this by default
+ _flags->_concurrent = 1;
+ }
+ return self;
}
-+ (id)allocWithZone:(NSZone *)aZone
+- (void)dealloc
{
- return FVOperationClass == self ? defaultPlaceholderOperation : [super
allocWithZone:aZone];
+ NSZoneFree([self zone], (void *)_flags);
+ [_queue release];
+ [super dealloc];
}
-// ensure that alloc always calls through to allocWithZone:
-+ (id)alloc
-{
- return [self allocWithZone:NULL];
-}
-
-- (id)init
-{
- self = [super init];
- return self;
-}
-
- (NSUInteger)hash
{
return [super hash];
@@ -92,24 +87,63 @@
return [NSString stringWithFormat:@"%@ = {\n\t cancelled = %d,\n\t
priority = %d,\n}\n", [super description], [self isCancelled], [self
queuePriority]];
}
-// Subclass responsibility
+- (FVOperationQueuePriority)queuePriority {
+ return _flags->_priority;
+};
-- (FVOperationQueuePriority)queuePriority { [self
doesNotRecognizeSelector:_cmd]; return 0; };
-- (void)setQueuePriority:(FVOperationQueuePriority)queuePriority { [self
doesNotRecognizeSelector:_cmd]; };
-- (void)cancel { [self doesNotRecognizeSelector:_cmd]; };
-- (BOOL)isCancelled { [self doesNotRecognizeSelector:_cmd]; return YES; };
-- (BOOL)isExecuting { [self doesNotRecognizeSelector:_cmd]; return YES; };
-- (BOOL)isFinished { [self doesNotRecognizeSelector:_cmd]; return YES; };
+- (void)setQueuePriority:(FVOperationQueuePriority)queuePriority {
+ bool didSwap;
+ do {
+ didSwap = OSAtomicCompareAndSwap32Barrier(_flags->_priority,
queuePriority, &(_flags->_priority));
+ } while (false == didSwap);
+};
+
+- (void)cancel {
+ // allow multiple calls to -cancel
+ OSAtomicIncrement32Barrier(&(_flags->_cancelled));
+};
+
+- (BOOL)isCancelled {
+ return 0 != _flags->_cancelled;
+};
+
+- (BOOL)isExecuting {
+ return 1 == _flags->_executing;
+};
+
+- (BOOL)isFinished {
+ return 1 == _flags->_finished;
+};
+
- (void)main { [self doesNotRecognizeSelector:_cmd]; }
-- (void)setQueue:(id)queue { [self doesNotRecognizeSelector:_cmd]; }
-- (id)queue { [self doesNotRecognizeSelector:_cmd]; return nil; };
-- (void)setConcurrent:(BOOL)flag { [self doesNotRecognizeSelector:_cmd]; }
-@end
+- (void)setQueue:(id)queue {
+ FVAPIAssert(nil == _queue, @"setQueue: may only be called once");
+ _queue = [queue retain];
+}
-@implementation FVOperation (Extended)
+- (id)queue {
+ return _queue;
+};
+- (BOOL)isConcurrent {
+ return 1 == _flags->_concurrent;
+}
+
+- (void)setConcurrent:(BOOL)flag {
+ if ([self isCancelled])
+ [NSException raise:NSInternalInconsistencyException format:@"attempt
to modify a cancelled operation"];
+ if ([self isExecuting] || [self isFinished])
+ [NSException raise:NSInternalInconsistencyException format:@"attempt
to modify a previously executed operation"];
+
+ bool didSwap;
+ int32_t val = flag ? 1 : 0;
+ do {
+ didSwap = OSAtomicCompareAndSwap32Barrier(_flags->_concurrent, val,
&(_flags->_concurrent));
+ } while (false == didSwap);
+}
+
// semantics here as the same as for NSDate, if we consider the dates as
absolute time values
- (NSComparisonResult)compare:(FVOperation *)other;
{
@@ -127,6 +161,8 @@
if ([self isExecuting] || [self isFinished])
[NSException raise:NSInternalInconsistencyException format:@"attempt
to start a previously executed operation"];
+ OSAtomicIncrement32Barrier(&(_flags->_executing));
+
if ([self isConcurrent])
[FVThread detachNewThreadSelector:@selector(main) toTarget:self
withObject:nil];
else
@@ -137,28 +173,7 @@
{
// Make sure the queue releases its reference to this operation. This
always happens if it's cancelled by the queue, but someone else could call
-cancel, in which case this might be left in the queue's activeOperations bag.
[[self queue] finishedOperation:self];
+ OSAtomicIncrement32Barrier(&(_flags->_finished));
}
-- (BOOL)isConcurrent { return NO; }
-
@end
-
-
-@implementation FVPlaceholderOperation
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
-- (id)init {
- return (id)[[FVConcreteOperation allocWithZone:[self zone]] init];
-}
-#pragma clang diagnostic pop
-
-- (id)retain { return self; }
-
-- (id)autorelease { return self; }
-
-- (oneway void)release {}
-
-- (NSUInteger)retainCount { return NSUIntegerMax; }
-
-@end
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m 2021-01-16
15:40:15 UTC (rev 25412)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m 2021-01-16
16:12:22 UTC (rev 25413)
@@ -38,7 +38,7 @@
#import "FVTextIcon.h"
#import "FVIcon_Private.h"
-#import "FVConcreteOperation.h"
+#import "FVOperation.h"
#import "FVOperationQueue.h"
@implementation FVTextIcon
Modified:
trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj
===================================================================
---
trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj
2021-01-16 15:40:15 UTC (rev 25412)
+++
trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj
2021-01-16 16:12:22 UTC (rev 25413)
@@ -43,8 +43,6 @@
CE8923350D7CBB10006D514C /* FVOperationQueue.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE05D5D10D7C223E0034C2A8 /* FVOperationQueue.m
*/; };
CE8923360D7CBB11006D514C /* FVPriorityQueue.h in Headers */ =
{isa = PBXBuildFile; fileRef = CE05D5D20D7C223E0034C2A8 /* FVPriorityQueue.h
*/; };
CE8923370D7CBB11006D514C /* FVPriorityQueue.mm in Sources */ =
{isa = PBXBuildFile; fileRef = CE05D5D30D7C223E0034C2A8 /* FVPriorityQueue.mm
*/; };
- CE8923380D7CBB14006D514C /* FVConcreteOperation.h in Headers */
= {isa = PBXBuildFile; fileRef = CE05D5E20D7C22550034C2A8 /*
FVConcreteOperation.h */; };
- CE8923390D7CBB15006D514C /* FVConcreteOperation.m in Sources */
= {isa = PBXBuildFile; fileRef = CE05D5E30D7C22550034C2A8 /*
FVConcreteOperation.m */; };
CE89233A0D7CBB16006D514C /* FVIconOperation.h in Headers */ =
{isa = PBXBuildFile; fileRef = CE05D5E40D7C22550034C2A8 /* FVIconOperation.h
*/; };
CE89233B0D7CBB17006D514C /* FVIconOperation.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE05D5E50D7C22550034C2A8 /* FVIconOperation.m
*/; };
CE89233C0D7CBB17006D514C /* FVInvocationOperation.h in Headers
*/ = {isa = PBXBuildFile; fileRef = CE05D5E60D7C22550034C2A8 /*
FVInvocationOperation.h */; };
@@ -180,8 +178,6 @@
CE05D5D30D7C223E0034C2A8 /* FVPriorityQueue.mm */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp;
path = FVPriorityQueue.mm; sourceTree = "<group>"; };
CE05D5D40D7C223E0034C2A8 /* FVConcreteOperationQueue.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
path = FVConcreteOperationQueue.h; sourceTree = "<group>"; };
CE05D5D50D7C223E0034C2A8 /* FVConcreteOperationQueue.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; path = FVConcreteOperationQueue.m; sourceTree = "<group>"; };
- CE05D5E20D7C22550034C2A8 /* FVConcreteOperation.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
FVConcreteOperation.h; sourceTree = "<group>"; };
- CE05D5E30D7C22550034C2A8 /* FVConcreteOperation.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= FVConcreteOperation.m; sourceTree = "<group>"; };
CE05D5E40D7C22550034C2A8 /* FVIconOperation.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
FVIconOperation.h; sourceTree = "<group>"; };
CE05D5E50D7C22550034C2A8 /* FVIconOperation.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= FVIconOperation.m; sourceTree = "<group>"; };
CE05D5E60D7C22550034C2A8 /* FVInvocationOperation.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
FVInvocationOperation.h; sourceTree = "<group>"; };
@@ -491,8 +487,6 @@
CE05D5CD0D7C22070034C2A8 /* Operations */ = {
isa = PBXGroup;
children = (
- CE05D5E20D7C22550034C2A8 /*
FVConcreteOperation.h */,
- CE05D5E30D7C22550034C2A8 /*
FVConcreteOperation.m */,
CE05D5E40D7C22550034C2A8 /* FVIconOperation.h
*/,
CE05D5E50D7C22550034C2A8 /* FVIconOperation.m
*/,
CE05D5E60D7C22550034C2A8 /*
FVInvocationOperation.h */,
@@ -625,7 +619,6 @@
CE8923320D7CBB0E006D514C /*
FVMainThreadOperationQueue.h in Headers */,
CE8923340D7CBB0F006D514C /* FVOperationQueue.h
in Headers */,
CE8923360D7CBB11006D514C /* FVPriorityQueue.h
in Headers */,
- CE8923380D7CBB14006D514C /*
FVConcreteOperation.h in Headers */,
CE89233A0D7CBB16006D514C /* FVIconOperation.h
in Headers */,
CE89233C0D7CBB17006D514C /*
FVInvocationOperation.h in Headers */,
CE89233E0D7CBB19006D514C /* FVOperation.h in
Headers */,
@@ -788,7 +781,6 @@
CE8923330D7CBB0E006D514C /*
FVMainThreadOperationQueue.m in Sources */,
CE8923350D7CBB10006D514C /* FVOperationQueue.m
in Sources */,
CE8923370D7CBB11006D514C /* FVPriorityQueue.mm
in Sources */,
- CE8923390D7CBB15006D514C /*
FVConcreteOperation.m in Sources */,
CE89233B0D7CBB17006D514C /* FVIconOperation.m
in Sources */,
CE89233D0D7CBB18006D514C /*
FVInvocationOperation.m in Sources */,
CE89233F0D7CBB1A006D514C /* FVOperation.m in
Sources */,
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit