Skip to content

Commit

Permalink
Merge pull request #2038 from sptramer/timob-8314
Browse files Browse the repository at this point in the history
[TIMOB-8314] Force explicit synchronization during JSCore calls.
  • Loading branch information
Max Stepanov committed Apr 20, 2012
2 parents bf50e3f + 62197ae commit bb163c2
Showing 1 changed file with 52 additions and 24 deletions.
76 changes: 52 additions & 24 deletions iphone/Classes/KrollContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
static unsigned short KrollContextIdCounter = 0;
static unsigned short KrollContextCount = 0;

static pthread_rwlock_t KrollGarbageCollectionLock;
static pthread_mutex_t KrollEntryLock;

@implementation KrollUnprotectOperation

Expand Down Expand Up @@ -69,6 +69,7 @@ -(id)initWithTarget:(id)target_ method:(SEL)method_ withObject:(id)obj_ conditio
}
return self;
}

-(id)initWithTarget:(id)target_ method:(SEL)method_ withObject:(id)obj_ callback:(id)callback_ selector:(SEL)selector_
{
if (self = [super init])
Expand All @@ -81,6 +82,7 @@ -(id)initWithTarget:(id)target_ method:(SEL)method_ withObject:(id)obj_ callback
}
return self;
}

-(void)dealloc
{
[target release];
Expand All @@ -89,22 +91,33 @@ -(void)dealloc
[notify release];
[super dealloc];
}

-(void)invoke:(KrollContext*)context
{
if (target!=nil)
{
[target performSelector:method withObject:obj withObject:context];
}
if (condition!=nil)
{
[condition lock];
[condition signal];
[condition unlock];
}
if (notify!=nil)
{
[notify performSelector:notifySelector];
}
pthread_mutex_lock(&KrollEntryLock);

@try {
if (target!=nil)
{
[target performSelector:method withObject:obj withObject:context];
}
if (condition!=nil)
{
[condition lock];
[condition signal];
[condition unlock];
}
if (notify!=nil)
{
[notify performSelector:notifySelector];
}
}
@catch (NSException* e) {
@throw e;
}
@finally {
pthread_mutex_unlock(&KrollEntryLock);
}
}

@end
Expand Down Expand Up @@ -563,18 +576,21 @@ -(void)dealloc

-(TiValueRef) jsInvokeInContext: (KrollContext*)context exception: (TiValueRef *)exceptionPointer
{
pthread_mutex_lock(&KrollEntryLock);
TiStringRef js = TiStringCreateWithCFString((CFStringRef) code);
TiObjectRef global = TiContextGetGlobalObject([context context]);

TiValueRef result = TiEvalScript([context context], js, global, NULL, 1, exceptionPointer);

TiStringRelease(js);
pthread_mutex_unlock(&KrollEntryLock);

return result;
}

-(void)invoke:(KrollContext*)context
{
pthread_mutex_lock(&KrollEntryLock);
TiValueRef exception = NULL;
[self jsInvokeInContext:context exception:&exception];

Expand All @@ -584,10 +600,12 @@ -(void)invoke:(KrollContext*)context
NSLog(@"[ERROR] Script Error = %@",[TiUtils exceptionMessage:excm]);
fflush(stderr);
}
pthread_mutex_unlock(&KrollEntryLock);
}

-(id)invokeWithResult:(KrollContext*)context
{
pthread_mutex_lock(&KrollEntryLock);
TiValueRef exception = NULL;
TiValueRef result = [self jsInvokeInContext:context exception:&exception];

Expand All @@ -596,8 +614,12 @@ -(id)invokeWithResult:(KrollContext*)context
id excm = [KrollObject toID:context value:exception];
NSLog(@"[ERROR] Script Error = %@",[TiUtils exceptionMessage:excm]);
fflush(stderr);

pthread_mutex_unlock(&KrollEntryLock);
@throw excm;
}
pthread_mutex_unlock(&KrollEntryLock);

return [KrollObject toID:context value:result];
}

Expand Down Expand Up @@ -640,6 +662,7 @@ -(void)dealloc
}
-(void)invoke:(KrollContext*)context
{
pthread_mutex_lock(&KrollEntryLock);
if(callbackObject != nil)
{
[callbackObject triggerEvent:type withObject:eventObject thisObject:thisObject];
Expand All @@ -649,6 +672,7 @@ -(void)invoke:(KrollContext*)context
{
[callback call:[NSArray arrayWithObject:eventObject] thisObject:thisObject];
}
pthread_mutex_unlock(&KrollEntryLock);
}
@end

Expand All @@ -661,7 +685,10 @@ +(void)initialize
{
if(self == [KrollContext class])
{
pthread_rwlock_init(&KrollGarbageCollectionLock, NULL);
pthread_mutexattr_t entryLockAttrs;
pthread_mutexattr_init(&entryLockAttrs);
pthread_mutexattr_settype(&entryLockAttrs, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&KrollEntryLock, &entryLockAttrs);
}
}

Expand Down Expand Up @@ -870,17 +897,16 @@ -(BOOL)isKJSThread

-(void)invoke:(id)object
{
pthread_rwlock_rdlock(&KrollGarbageCollectionLock);
//Mwahahaha! Pre-emptively putting in NSOperations before the Queue.
pthread_mutex_lock(&KrollEntryLock);
if([object isKindOfClass:[NSOperation class]])
{
[(NSOperation *)object start];
pthread_rwlock_unlock(&KrollGarbageCollectionLock);
pthread_mutex_unlock(&KrollEntryLock);
return;
}

[object invoke:self];
pthread_rwlock_unlock(&KrollGarbageCollectionLock);
pthread_mutex_unlock(&KrollEntryLock);
}

-(void)enqueue:(id)obj
Expand Down Expand Up @@ -952,7 +978,9 @@ -(void)invokeOnThread:(id)callback_ method:(SEL)method_ withObject:(id)obj callb
-(void)invokeBlockOnThread:(void (^)())block
{
if ([self isKJSThread]) {
pthread_mutex_lock(&KrollEntryLock);
block();
pthread_mutex_unlock(&KrollEntryLock);
return;
}
NSBlockOperation* blockOp = [NSBlockOperation blockOperationWithBlock:block];
Expand Down Expand Up @@ -995,9 +1023,9 @@ -(int)forceGarbageCollectNow
#if CONTEXT_DEBUG == 1
NSLog(@"CONTEXT<%@>: forced garbage collection requested",self);
#endif
pthread_rwlock_wrlock(&KrollGarbageCollectionLock);
pthread_mutex_lock(&KrollEntryLock);
TiGarbageCollect(context);
pthread_rwlock_unlock(&KrollGarbageCollectionLock);
pthread_mutex_unlock(&KrollEntryLock);
gcrequest = NO;
loopCount = 0;
[garbagePool drain];
Expand All @@ -1010,7 +1038,7 @@ -(void)main
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSThread currentThread] setName:[self threadName]];
cachedThreadId = [NSThread currentThread];
pthread_rwlock_rdlock(&KrollGarbageCollectionLock);
pthread_mutex_lock(&KrollEntryLock);
// context = TiGlobalContextCreateInGroup([TiApp contextGroup],NULL);
context = TiGlobalContextCreate(NULL);
TiObjectRef globalRef = TiContextGetGlobalObject(context);
Expand Down Expand Up @@ -1115,7 +1143,7 @@ -(void)main
{
[delegate performSelector:@selector(didStartNewContext:) withObject:self];
}
pthread_rwlock_unlock(&KrollGarbageCollectionLock);
pthread_mutex_unlock(&KrollEntryLock);

BOOL exit_after_flush = NO;

Expand Down

0 comments on commit bb163c2

Please sign in to comment.