improvements for thread safety ... use main thread for connections

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@37887 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2014-05-16 16:24:28 +00:00
parent 96d11d9869
commit c4dc8d4489
3 changed files with 90 additions and 44 deletions

View file

@ -1,3 +1,9 @@
2014-05-16 Richard Frith-Macdonald <rfm@gnu.org>
EcAlarmDestination.m: Perform all connection operations in
main thread (forwarding etc) and ensure that we run the
current run loop while waiting for startup and shutdown.
2014-05-14 Richard Frith-Macdonald <rfm@gnu.org>
* EcAlerter.m: fix bug processing alert emails

View file

@ -205,7 +205,8 @@
@end
/** Methods called internally to forward events to the remote target of
* the receiver. These are provided for subclasses to override.
* the receiver.
* These methods must perform themselves in the main thread.
*/
@interface EcAlarmDestination (Forwarding)
/** Forward an alarm event. */

View file

@ -36,6 +36,10 @@
@interface EcAlarmDestination (Private)
/* Make connection to destination host.
*/
- (void) _connect;
/* Loss of connection ... clear destination.
*/
- (void) _connectionBecameInvalid: (id)connection;
@ -137,6 +141,8 @@
begin = [NSDate date];
while (NO == [self isRunning])
{
NSDate *when;
if ([begin timeIntervalSinceNow] < -5.0)
{
NSLog(@"alarm thread failed to start within 5 seconds");
@ -146,7 +152,9 @@
[self release];
return nil;
}
[NSThread sleepForTimeInterval: 0.1];
when = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: when];
[when release];
}
}
return self;
@ -295,12 +303,16 @@
begin = [NSDate date];
while (YES == [self isRunning])
{
NSDate *when;
if ([begin timeIntervalSinceNow] < -5.0)
{
NSLog(@"alarm thread failed to stop within 5 seconds");
return;
}
[NSThread sleepForTimeInterval: 0.1];
when = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: when];
[when release];
}
}
@ -340,20 +352,7 @@
@implementation EcAlarmDestination (Private)
- (void) _connectionBecameInvalid: (id)connection
{
[self setDestination: nil];
}
- (void) _timeout: (NSTimer*)t
{
[_alarmLock lock];
if (NO == _inTimeout && YES == _isRunning)
{
_inTimeout = YES;
NS_DURING
{
if ([_alarmQueue count] > 0)
- (void) _connect
{
if (nil == (id)_destination)
{
@ -392,6 +391,23 @@
}
}
}
}
- (void) _connectionBecameInvalid: (id)connection
{
[self setDestination: nil];
}
- (void) _timeout: (NSTimer*)t
{
[_alarmLock lock];
if (NO == _inTimeout && YES == _isRunning)
{
_inTimeout = YES;
NS_DURING
{
if ([_alarmQueue count] > 0)
{
// Do stuff here
while ([_alarmQueue count] > 0)
@ -461,7 +477,6 @@
[_managedObjects addObject: m];
[self domanageFwd: m];
}
[self alarmFwd: next];
}
}
@ -504,7 +519,7 @@
{
if (YES == [s hasPrefix: m])
{
[self _unmanage: s];
[self unmanageFwd: s];
}
}
}
@ -571,7 +586,14 @@
- (void) alarmFwd: (EcAlarm*)event
{
if (NO == [NSThread isMainThread])
{
[self performSelectorOnMainThread: _cmd withObject: event waitUntilDone: NO];
return;
}
[_alarmLock lock];
NS_DURING
[self _connect];
[_destination alarm: event];
NS_DURING
[_backups makeObjectsPerformSelector: @selector(alarm:)
@ -584,11 +606,19 @@
[self setDestination: nil];
NSLog(@"Problem sending alarm to destination ... %@", localException);
NS_ENDHANDLER
[_alarmLock unlock];
}
- (void) domanageFwd: (NSString*)managedObject
{
if (NO == [NSThread isMainThread])
{
[self performSelectorOnMainThread: _cmd withObject: managedObject waitUntilDone: NO];
return;
}
[_alarmLock lock];
NS_DURING
[self _connect];
[_destination domanage: managedObject];
NS_DURING
[_backups makeObjectsPerformSelector: @selector(domanage:)
@ -601,11 +631,19 @@
[self setDestination: nil];
NSLog(@"Problem with domanage to destination ... %@", localException);
NS_ENDHANDLER
[_alarmLock unlock];
}
- (void) unmanageFwd: (NSString*)managedObject
{
if (NO == [NSThread isMainThread])
{
[self performSelectorOnMainThread: _cmd withObject: managedObject waitUntilDone: NO];
return;
}
[_alarmLock lock];
NS_DURING
[self _connect];
[_destination unmanage: managedObject];
NS_DURING
[_backups makeObjectsPerformSelector: @selector(unmanage:)
@ -618,6 +656,7 @@
[self setDestination: nil];
NSLog(@"Problem with unmanage to destination ... %@", localException);
NS_ENDHANDLER
[_alarmLock unlock];
}
@end