Author: rfm
Date: Thu Apr 2 17:59:48 2015
New Revision: 38448
URL: http://svn.gna.org/viewcvs/gnustep?rev=38448&view=rev
Log:
Try to better handle exception in method in another thread
Modified:
libs/base/trunk/ChangeLog
libs/base/trunk/Source/NSThread.m
Modified: libs/base/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/ChangeLog?rev=38448&r1=38447&r2=38448&view=diff
==============================================================================
--- libs/base/trunk/ChangeLog (original)
+++ libs/base/trunk/ChangeLog Thu Apr 2 17:59:48 2015
@@ -1,3 +1,9 @@
+2015-04-02 Richard Frith-Macdonald <[email protected]>
+
+ * Source/NSThread.m: If an exception occurs while performing a
+ selector in another thread, catch it and cleanup (and if the
+ caller is waiting, pass the exception back to it).
+
2015-04-01 Wolfgang Lux <[email protected]>
* configure.ac: Fix comment syntax and use standard operator in
Modified: libs/base/trunk/Source/NSThread.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSThread.m?rev=38448&r1=38447&r2=38448&view=diff
==============================================================================
--- libs/base/trunk/Source/NSThread.m (original)
+++ libs/base/trunk/Source/NSThread.m Thu Apr 2 17:59:48 2015
@@ -222,6 +222,8 @@
NSConditionLock *lock; // Not retained.
NSArray *modes;
BOOL invalidated;
+@public
+ NSException *exception;
}
+ (GSPerformHolder*) newForReceiver: (id)r
argument: (id)a
@@ -1286,6 +1288,7 @@
- (void) dealloc
{
+ DESTROY(exception);
DESTROY(receiver);
DESTROY(argument);
DESTROY(modes);
@@ -1309,7 +1312,23 @@
}
threadInfo = GSRunLoopInfoForThread(GSCurrentThread());
[threadInfo->loop cancelPerformSelectorsWithTarget: self];
- [receiver performSelector: selector withObject: argument];
+ NS_DURING
+ {
+ [receiver performSelector: selector withObject: argument];
+ }
+ NS_HANDLER
+ {
+ ASSIGN(exception, localException);
+ if (nil == lock)
+ {
+ NSLog(@"*** NSRunLoop ignoring exception '%@' (reason '%@') "
+ @"raised during perform in other thread... with receiver %p "
+ @"and selector '%@'",
+ [localException name], [localException reason], receiver,
+ NSStringFromSelector(selector));
+ }
+ }
+ NS_ENDHANDLER
DESTROY(receiver);
DESTROY(argument);
DESTROY(modes);
@@ -1452,9 +1471,19 @@
RELEASE(l);
if ([h isInvalidated] == YES)
{
+ RELEASE(h);
[NSException raise: NSInternalInconsistencyException
format: @"perform on finished thread"];
+ }
+ /* If we have an exception passed back from the remote thread,
+ * re-raise it.
+ */
+ if (nil != h->exception)
+ {
+ NSException *e = AUTORELEASE(RETAIN(h->exception));
+
RELEASE(h);
+ [e raise];
}
}
RELEASE(h);
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs