machrunloopserver.cpp [plain text]
#include "machrunloopserver.h"
#include <security_utilities/cfutilities.h>
#include <mach/mach_error.h>
#include <security_utilities/debugging.h>
namespace Security {
namespace MachPlusPlus {
MachRunLoopServer::MachRunLoopServer(const char *name)
: MachServer(name), CFAutoPort(primaryServicePort())
{
}
MachRunLoopServer::MachRunLoopServer(const char *name, const Bootstrap &boot)
: MachServer(name, boot), CFAutoPort(primaryServicePort())
{
}
void MachRunLoopServer::run(mach_msg_size_t bufferSize, mach_msg_options_t options)
{
mReplyMessage.setBuffer(bufferSize);
CFAutoPort::enable();
perThread().server = this;
}
MachRunLoopServer::~MachRunLoopServer()
{
perThread().server = NULL;
}
void MachRunLoopServer::notifyIfDead(Port port, bool doNotify) const
{
if (CFMachPortRef cfPort = CFMachPortCreateWithPort(NULL, port, NULL, NULL, NULL))
CFMachPortSetInvalidationCallBack(cfPort, cfInvalidate);
}
void MachRunLoopServer::cfInvalidate(CFMachPortRef cfPort, void *context)
{
reinterpret_cast<MachRunLoopServer *>(context)->notifyDeadName(CFMachPortGetPort(cfPort));
}
void MachRunLoopServer::receive(const Message &request)
{
active().oneRequest(request);
}
void MachRunLoopServer::oneRequest(const Message &request)
{
if (!handle(request, mReplyMessage)) { secinfo("machrls", "MachRunLoopServer dispatch failed");
} else {
mReplyMessage.send((MACH_MSGH_BITS_REMOTE(mReplyMessage.bits()) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ?
MACH_SEND_MSG : MACH_SEND_MSG|MACH_SEND_TIMEOUT);
}
active().releaseDeferredAllocations();
}
} }