Author: rfm
Date: Sun Jan 31 18:54:32 2016
New Revision: 39324
URL: http://svn.gna.org/viewcvs/gnustep?rev=39324&view=rev
Log:
Add delay period for alarm, to allow coalesching within the queue and add
hysteresis so we won't forward alarms which are cleared shortly after being
raised.
Modified:
libs/ec/trunk/ChangeLog
libs/ec/trunk/EcAlarm.h
libs/ec/trunk/EcAlarm.m
libs/ec/trunk/EcAlarmDestination.m
Modified: libs/ec/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/ChangeLog?rev=39324&r1=39323&r2=39324&view=diff
==============================================================================
--- libs/ec/trunk/ChangeLog (original)
+++ libs/ec/trunk/ChangeLog Sun Jan 31 18:54:32 2016
@@ -1,3 +1,14 @@
+2016-01-21 Richard Frith-Macdonald <[email protected]>
+
+ * EcAlarm.h:
+ * EcAlarm.m:
+ * EcAlarmDestination.m: When coalescing alarms, allow a clear and
+ alarm to cancel each other out, but only if the alarm is not yet
+ active (only queued). Allow alarms to be set to persist in the queue
+ for up to 255 seconds to allow more coalescing.
+ This lets us raise an alarm which, if cleared within the delay
+ period, will never be forwarded anywhere.
+
2015-11-18 Richard Frith-Macdonald <[email protected]>
* EcProcess.m: Improve output when changing/reading defaults, and
Modified: libs/ec/trunk/EcAlarm.h
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcAlarm.h?rev=39324&r1=39323&r2=39324&view=diff
==============================================================================
--- libs/ec/trunk/EcAlarm.h (original)
+++ libs/ec/trunk/EcAlarm.h Sun Jan 31 18:54:32 2016
@@ -350,6 +350,7 @@
NSDictionary *_userInfo;
void *_extra;
BOOL _frozen;
+ uint8_t _delay;
}
/** Creates and returns an autoreleased instance by calling the
@@ -427,6 +428,15 @@
/** Deallocates the receiver.
*/
- (void) dealloc;
+
+/** Returns the queue delay set for this alarm (or zero if none was set).
+ */
+- (uint8_t) delay;
+
+/** Returns YES if the receiver should be delayed in the queue past the
+ * supplied timestamp, NO otherwise.
+ */
+- (BOOL) delayed: (NSTimeInterval)at;
/** EcAlarm objects may be passed over the distributed objects system or
* archived. This method is provided to implement the NSCoding protocol.<br />
@@ -541,6 +551,13 @@
/** Returns the probableCause set when the receiver was initialised.
*/
- (EcAlarmProbableCause) probableCause;
+
+/** Sets the number of seconds for which this alarm should be delayed in the
+ * queue to allow coalescing with other matching alarms. This defaults to
+ * zero so that there is no special delay in processing beyond that imposed
+ * by periodic queue flushing.
+ */
+- (void) setDelay: (uint8_t)delay;
/** Sets extra data for the current instance.<br />
* Extra data is not copied, archived, or transferred over DO, it is available
Modified: libs/ec/trunk/EcAlarm.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcAlarm.m?rev=39324&r1=39323&r2=39324&view=diff
==============================================================================
--- libs/ec/trunk/EcAlarm.m (original)
+++ libs/ec/trunk/EcAlarm.m Sun Jan 31 18:54:32 2016
@@ -456,6 +456,7 @@
c->_firstEventDate = [_firstEventDate copyWithZone: aZone];
c->_notificationID = _notificationID;
c->_trendIndicator = _trendIndicator;
+ c->_delay = _delay;
ASSIGNCOPY(c->_userInfo, _userInfo);
}
return c;
@@ -471,6 +472,23 @@
DESTROY(_proposedRepairAction);
DESTROY(_additionalText);
[super dealloc];
+}
+
+- (uint8_t) delay
+{
+ return _delay;
+}
+
+- (BOOL) delayed: (NSTimeInterval)at
+{
+ if (_delay > 0)
+ {
+ if (at < [_eventDate timeIntervalSinceReferenceDate] + _delay)
+ {
+ return YES;
+ }
+ }
+ return NO;
}
- (NSString*) description
@@ -849,6 +867,17 @@
return self;
}
+- (void) setDelay: (uint8_t)delay
+{
+ if (YES == _frozen)
+ {
+ [NSException raise: NSInternalInconsistencyException
+ format: @"[%@-%@] called for frozen instance",
+ NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
+ }
+ _delay = delay;
+}
+
- (void) setExtra: (void*)extra
{
if (YES == _frozen)
Modified: libs/ec/trunk/EcAlarmDestination.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcAlarmDestination.m?rev=39324&r1=39323&r2=39324&view=diff
==============================================================================
--- libs/ec/trunk/EcAlarmDestination.m (original)
+++ libs/ec/trunk/EcAlarmDestination.m Sun Jan 31 18:54:32 2016
@@ -75,25 +75,40 @@
{
NSUInteger index;
- /* Event clears may only be coalesced with other clears,
- * otherwise we might have a case where a clear is sent
- * to the alarm sink without a corresponding alarm having
- * been raised.
- */
index = [_alarmQueue indexOfObject: event];
- [_alarmQueue addObject: event];
- if (NSNotFound != index)
+ if (NSNotFound == index)
+ {
+ [_alarmQueue addObject: event];
+ }
+ else
{
EcAlarm *old = [_alarmQueue objectAtIndex: index];
if ([old perceivedSeverity] == EcAlarmSeverityCleared)
{
+ /* Repeated clears may be coalesced with later clears
+ * being ignored.
+ */
if (YES == _debug)
{
- NSLog(@"Coalesce %@ by removing %@", event, old);
+ NSLog(@"Coalesce %@ by dropping it (%@ exists)",
+ event, old);
+ }
+ [_alarmQueue addObject: event];
+ [_alarmQueue removeObjectAtIndex: index];
+ }
+ else if (nil == [_alarmsActive member: old])
+ {
+ /* An alarm which is not yet active may be cancelled-out
+ * by a following clear.
+ */
+ if (YES == _debug)
+ {
+ NSLog(@"Coalesce %@ by removing %@ (old)",
+ event, old);
}
[_alarmQueue removeObjectAtIndex: index];
- }
+ }
}
}
else
@@ -101,16 +116,32 @@
NSUInteger index;
index = [_alarmQueue indexOfObject: event];
- [_alarmQueue addObject: event];
- if (NSNotFound != index)
+ if (NSNotFound == index)
+ {
+ [_alarmQueue addObject: event];
+ }
+ else
{
EcAlarm *old = [_alarmQueue objectAtIndex: index];
- if (YES == _debug)
+ if ([old perceivedSeverity] == EcAlarmSeverityCleared)
{
- NSLog(@"Coalesce %@ by removing %@", event, old);
+ [_alarmQueue addObject: event];
+ if (YES == _debug)
+ {
+ NSLog(@"Coalesce %@ by removing %@ (old)",
+ event, old);
+ }
+ [_alarmQueue removeObjectAtIndex: index];
}
- [_alarmQueue removeObjectAtIndex: index];
+ else
+ {
+ if (YES == _debug)
+ {
+ NSLog(@"Coalesce %@ by dropping it (%@ exists)",
+ event, old);
+ }
+ }
}
}
[_alarmLock unlock];
@@ -499,21 +530,81 @@
{
if ([_alarmQueue count] > 0)
{
+ NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
+ NSUInteger index = 0;
+
// Do stuff here
- while ([_alarmQueue count] > 0)
+ while (index < [_alarmQueue count])
{
- id o;
-
- o = [[[_alarmQueue objectAtIndex: 0] retain] autorelease];
- [_alarmQueue removeObjectAtIndex: 0];
-
- if (YES == [o isKindOfClass: [EcAlarm class]])
+ id o = [_alarmQueue objectAtIndex: index];
+
+ if (NO == [o isKindOfClass: [EcAlarm class]])
{
- EcAlarm *next = (EcAlarm*)o;
+ NSString *s = RETAIN([o description]);
+
+ [_alarmQueue removeObjectAtIndex: index];
+
+ if (YES == [s hasPrefix: @"domanage "])
+ {
+ NSString *m = [s substringFromIndex: 9];
+
+ if (nil == [_managedObjects member: m])
+ {
+ [_managedObjects addObject: m];
+ [_alarmLock unlock];
+ [self domanageFwd: m];
+ [_alarmLock lock];
+ }
+ }
+ else if (YES == [s hasPrefix: @"unmanage "])
+ {
+ NSString *m = [s substringFromIndex: 9];
+
+ if (nil != [_managedObjects member: m])
+ {
+ [_alarmLock unlock];
+ [self _unmanage: m];
+ [self unmanageFwd: m];
+ [_alarmLock lock];
+ }
+
+ /* When we unmanage an object, we also
+ * implicitly unmanage objects which
+ * are components of that object.
+ */
+ if (YES == [m hasSuffix: @"_"])
+ {
+ NSEnumerator *e;
+ NSString *c;
+
+ e = [[_managedObjects allObjects]
+ objectEnumerator];
+ while (nil != (c = [e nextObject]))
+ {
+ if (YES == [c hasPrefix: m])
+ {
+ [_alarmLock unlock];
+ [self unmanageFwd: c];
+ [_alarmLock lock];
+ }
+ }
+ }
+ }
+ else
+ {
+ NSLog(@"ERROR ... unexpected command '%@'", s);
+ }
+ RELEASE(s);
+ }
+ else if (NO == [(EcAlarm*)o delayed: now])
+ {
+ EcAlarm *next = (EcAlarm*)AUTORELEASE(RETAIN(o));
EcAlarm *prev = [_alarmsActive member: next];
NSString *m = [next managedObject];
BOOL shouldForward = NO;
+
+ [_alarmQueue removeObjectAtIndex: index];
if (nil == prev)
{
@@ -584,61 +675,13 @@
[_alarmLock lock];
}
}
- else
- {
- NSString *s = [o description];
-
- if (YES == [s hasPrefix: @"domanage "])
- {
- NSString *m = [s substringFromIndex: 9];
-
- if (nil == [_managedObjects member: m])
- {
- [_managedObjects addObject: m];
- [_alarmLock unlock];
- [self domanageFwd: m];
- [_alarmLock lock];
- }
- }
- else if (YES == [s hasPrefix: @"unmanage "])
- {
- NSString *m = [s substringFromIndex: 9];
-
- if (nil != [_managedObjects member: m])
- {
- [_alarmLock unlock];
- [self _unmanage: m];
- [self unmanageFwd: m];
- [_alarmLock lock];
- }
-
- /* When we unmanage an object, we also
- * implicitly unmanage objects which
- * are components of that object.
- */
- if (YES == [m hasSuffix: @"_"])
- {
- NSEnumerator *e;
- NSString *s;
-
- e = [[_managedObjects allObjects]
- objectEnumerator];
- while (nil != (s = [e nextObject]))
- {
- if (YES == [s hasPrefix: m])
- {
- [_alarmLock unlock];
- [self unmanageFwd: s];
- [_alarmLock lock];
- }
- }
- }
- }
- else
- {
- NSLog(@"ERROR ... unexpected command '%@'", s);
- }
- }
+ else
+ {
+ /* This alarm is delayed, skip past to process the
+ * next one.
+ */
+ index++;
+ }
}
}
_inTimeout = NO;
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs