+++ /dev/null
-#include "Monitor.h"
-#include <Block.h>
-#include "misc.h"
-#include "GroupTransform.h"
-#include "Utilities.h"
-
-void Monitor::Wait()
-{
-}
-
-
-
-bool Monitor::IsExternalizable()
-{
- return false; // monitors aren't really part of the transform
-}
-
-void BlockMonitor::AttributeChanged(CFStringRef name, CFTypeRef value)
-{
- // deliver the attribute to the queue
- CFTypeRef realValue = value;
- CFErrorRef error = NULL;
- bool isFinal = false;
-
- if (mSeenFinal)
- {
- // A NULL and CFErrorRef might both be enqueued already, and the 2nd can race the teardown. Without this check we would trigger final processing
- // more then once resulting in our own overlease issues, and could well cause our client to make similar errors.
- return;
- }
-
- if (realValue != NULL)
- {
- // do some basic checking
- if (CFGetTypeID(value) == CFErrorGetTypeID())
- {
- realValue = NULL;
- error = (CFErrorRef) value;
- isFinal = true;
- }
- }
- else
- {
- isFinal = true;
- }
-
- mSeenFinal = isFinal;
-
- if (realValue)
- {
- CFRetain(realValue);
- }
-
- if (mDispatchQueue == NULL)
- {
- mBlock(realValue, error, isFinal);
- }
- else
- {
- // ^{ mBlock } gets referenced via this (no retain), localBlock gets owned by
- // the block passed to dispatch_async
- SecMessageBlock localBlock = mBlock;
- dispatch_async(mDispatchQueue, ^{
- localBlock(realValue, error, isFinal);
- });
- }
-}
-
-
-
-BlockMonitor::BlockMonitor(dispatch_queue_t queue, SecMessageBlock block) : Monitor(CFSTR("BlockMonitor")), mDispatchQueue(queue), mSeenFinal(FALSE)
-{
- mBlock = ^(CFTypeRef value, CFErrorRef error, Boolean isFinal) {
- block(value, error, isFinal);
- if (value)
- {
- CFRelease(value);
- }
- if (isFinal && mGroup) {
- LastValueSent();
- }
- };
- mBlock = Block_copy(mBlock);
-}
-
-BlockMonitor::~BlockMonitor()
-{
- Block_release(mBlock);
-}
-
-void BlockMonitor::LastValueSent()
-{
- // The initial execute did a retain on our parent to keep it from
- // going out of scope. Since this chain is now done, release it.
- // NOTE: this needs to be the last thing we do otherwise *this
- // can be deleted out from under us, leading to a crash most frequently
- // inside the block we dispatch_async, sometimes inside of mBlock.
- Transform *rootGroup = this->GetRootGroup();
- CFTypeRef rootGroupRef = rootGroup->GetCFObject();
- dispatch_async(rootGroup->mDispatchQueue, ^{
- CFRelease(rootGroupRef);
- });
-}
-
-CFTypeRef BlockMonitor::Make(dispatch_queue_t queue, SecMessageBlock block)
-{
- return CoreFoundationHolder::MakeHolder(gInternalCFObjectName, new BlockMonitor(queue, block));
-}