mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-19 01:51:03 +00:00
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:
parent
96d11d9869
commit
c4dc8d4489
3 changed files with 90 additions and 44 deletions
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
|
||||
@interface EcAlarmDestination (Private)
|
||||
|
||||
/* Make connection to destination host.
|
||||
*/
|
||||
- (void) _connect;
|
||||
|
||||
/* Loss of connection ... clear destination.
|
||||
*/
|
||||
- (void) _connectionBecameInvalid: (id)connection;
|
||||
|
@ -123,8 +127,8 @@
|
|||
{
|
||||
NSDate *begin;
|
||||
|
||||
_host = [host copy];
|
||||
_name = [name copy];
|
||||
_host = [host copy];
|
||||
_name = [name copy];
|
||||
_alarmLock = [NSRecursiveLock new];
|
||||
_alarmQueue = [NSMutableArray new];
|
||||
_alarmsActive = [NSMutableSet new];
|
||||
|
@ -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,6 +352,47 @@
|
|||
|
||||
@implementation EcAlarmDestination (Private)
|
||||
|
||||
- (void) _connect
|
||||
{
|
||||
if (nil == (id)_destination)
|
||||
{
|
||||
if (nil != _name)
|
||||
{
|
||||
id proxy;
|
||||
|
||||
if (nil == _host)
|
||||
{
|
||||
proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName: _name
|
||||
host: _host
|
||||
usingNameServer:
|
||||
[NSMessagePortNameServer sharedInstance]];
|
||||
}
|
||||
else
|
||||
{
|
||||
proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName: _name
|
||||
host: _host
|
||||
usingNameServer:
|
||||
[NSSocketPortNameServer sharedInstance]];
|
||||
}
|
||||
|
||||
if (proxy != nil)
|
||||
{
|
||||
id connection = [proxy connectionForProxy];
|
||||
|
||||
[connection setDelegate: self];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_connectionBecameInvalid:)
|
||||
name: NSConnectionDidDieNotification
|
||||
object: connection];
|
||||
[self setDestination: (id<EcAlarmDestination>)proxy];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _connectionBecameInvalid: (id)connection
|
||||
{
|
||||
[self setDestination: nil];
|
||||
|
@ -355,43 +408,6 @@
|
|||
{
|
||||
if ([_alarmQueue count] > 0)
|
||||
{
|
||||
if (nil == (id)_destination)
|
||||
{
|
||||
if (nil != _name)
|
||||
{
|
||||
id proxy;
|
||||
|
||||
if (nil == _host)
|
||||
{
|
||||
proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName: _name
|
||||
host: _host
|
||||
usingNameServer:
|
||||
[NSMessagePortNameServer sharedInstance]];
|
||||
}
|
||||
else
|
||||
{
|
||||
proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName: _name
|
||||
host: _host
|
||||
usingNameServer:
|
||||
[NSSocketPortNameServer sharedInstance]];
|
||||
}
|
||||
|
||||
if (proxy != nil)
|
||||
{
|
||||
id connection = [proxy connectionForProxy];
|
||||
|
||||
[connection setDelegate: self];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_connectionBecameInvalid:)
|
||||
name: NSConnectionDidDieNotification
|
||||
object: connection];
|
||||
[self setDestination: (id<EcAlarmDestination>)proxy];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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
|
||||
|
|
Loading…
Reference in a new issue