#include "Monitor.h"
#include <Block.h>
#include "misc.h"
#include "GroupTransform.h"
#include "Utilities.h"
void Monitor::Wait()
{
}
bool Monitor::IsExternalizable()
{
return false; }
void BlockMonitor::AttributeChanged(CFStringRef name, CFTypeRef value)
{
CFTypeRef realValue = value;
CFErrorRef error = NULL;
bool isFinal = false;
if (mSeenFinal)
{
return;
}
if (realValue != NULL)
{
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
{
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()
{
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));
}