~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to thirdparty/SPMediaKeyTap/SPInvocationGrabbing/NSObject+SPInvocationGrabbing.m

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#import "NSObject+SPInvocationGrabbing.h"
 
2
#import <execinfo.h>
 
3
 
 
4
#pragma mark Invocation grabbing
 
5
@interface SPInvocationGrabber ()
 
6
@property (readwrite, retain, nonatomic) id object;
 
7
@property (readwrite, retain, nonatomic) NSInvocation *invocation;
 
8
 
 
9
@end
 
10
 
 
11
@implementation SPInvocationGrabber
 
12
- (id)initWithObject:(id)obj;
 
13
{
 
14
        return [self initWithObject:obj stacktraceSaving:YES];
 
15
}
 
16
 
 
17
-(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack;
 
18
{
 
19
        self.object = obj;
 
20
 
 
21
        if(saveStack)
 
22
                [self saveBacktrace];
 
23
 
 
24
        return self;
 
25
}
 
26
-(void)dealloc;
 
27
{
 
28
        free(frameStrings);
 
29
        self.object = nil;
 
30
        self.invocation = nil;
 
31
        [super dealloc];
 
32
}
 
33
@synthesize invocation = _invocation, object = _object;
 
34
 
 
35
@synthesize backgroundAfterForward, onMainAfterForward, waitUntilDone;
 
36
- (void)runInBackground;
 
37
{
 
38
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
39
        @try {
 
40
                [self invoke];
 
41
        }
 
42
        @finally {
 
43
                [pool drain];
 
44
        }
 
45
}
 
46
 
 
47
 
 
48
- (void)forwardInvocation:(NSInvocation *)anInvocation {
 
49
        [anInvocation retainArguments];
 
50
        anInvocation.target = _object;
 
51
        self.invocation = anInvocation;
 
52
        
 
53
        if(backgroundAfterForward)
 
54
                [NSThread detachNewThreadSelector:@selector(runInBackground) toTarget:self withObject:nil];
 
55
        else if(onMainAfterForward)
 
56
        [self performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:waitUntilDone];
 
57
}
 
58
- (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector {
 
59
        NSMethodSignature *signature = [super methodSignatureForSelector:inSelector];
 
60
        if (signature == NULL)
 
61
                signature = [_object methodSignatureForSelector:inSelector];
 
62
    
 
63
        return signature;
 
64
}
 
65
 
 
66
- (void)invoke;
 
67
{
 
68
 
 
69
        @try {
 
70
                [_invocation invoke];
 
71
        }
 
72
        @catch (NSException * e) {
 
73
                NSLog(@"SPInvocationGrabber's target raised %@:\n\t%@\nInvocation was originally scheduled at:", e.name, e);
 
74
                [self printBacktrace];
 
75
                printf("\n");
 
76
                [e raise];
 
77
        }
 
78
 
 
79
        self.invocation = nil;
 
80
        self.object = nil;
 
81
}
 
82
 
 
83
-(void)saveBacktrace;
 
84
{
 
85
  void *backtraceFrames[128];
 
86
  frameCount = backtrace(&backtraceFrames[0], 128);
 
87
  frameStrings = backtrace_symbols(&backtraceFrames[0], frameCount);
 
88
}
 
89
-(void)printBacktrace;
 
90
{
 
91
        int x;
 
92
        for(x = 3; x < frameCount; x++) {
 
93
                if(frameStrings[x] == NULL) { break; }
 
94
                printf("%s\n", frameStrings[x]);
 
95
        }
 
96
}
 
97
@end
 
98
 
 
99
@implementation NSObject (SPInvocationGrabbing)
 
100
-(id)grab;
 
101
{
 
102
        return [[[SPInvocationGrabber alloc] initWithObject:self] autorelease];
 
103
}
 
104
-(id)invokeAfter:(NSTimeInterval)delta;
 
105
{
 
106
        id grabber = [self grab];
 
107
        [NSTimer scheduledTimerWithTimeInterval:delta target:grabber selector:@selector(invoke) userInfo:nil repeats:NO];
 
108
        return grabber;
 
109
}
 
110
- (id)nextRunloop;
 
111
{
 
112
        return [self invokeAfter:0];
 
113
}
 
114
-(id)inBackground;
 
115
{
 
116
    SPInvocationGrabber *grabber = [self grab];
 
117
        grabber.backgroundAfterForward = YES;
 
118
        return grabber;
 
119
}
 
120
-(id)onMainAsync:(BOOL)async;
 
121
{
 
122
    SPInvocationGrabber *grabber = [self grab];
 
123
        grabber.onMainAfterForward = YES;
 
124
    grabber.waitUntilDone = !async;
 
125
        return grabber;
 
126
}
 
127
 
 
128
@end