ContextDataMachIPCStubs.cp [plain text]
/*
* CCIContextDataMachIPCStubs.cp
*
* $Header$
*/
#include "ContextDataMachIPCStubs.h"
extern "C" {
#include "CCacheIPC.h"
}
CCIContextDataMachIPCStub::CCIContextDataMachIPCStub (
CCIUniqueID inContextID,
CCIInt32 inAPIVersion):
CCIContext (inContextID, inAPIVersion) {
}
CCIContextDataMachIPCStub::CCIContextDataMachIPCStub (
CCIInt32 inAPIVersion):
CCIContext (GetGlobalContextID (), inAPIVersion) {
}
CCIContextDataMachIPCStub::~CCIContextDataMachIPCStub () {
}
CCITime
CCIContextDataMachIPCStub::GetChangeTime () {
CCIResult result;
mach_port_t port = GetPortNoLaunch ();
if (port != MACH_PORT_NULL) {
CCITime changeTime;
kern_return_t err = ContextIPC_GetChangeTime (port, GetContextID ().object, &changeTime, &result);
if (err != KERN_SUCCESS) {
// Special case this here because it isn't really an error.
// Server died == ccache changed now.
InvalidatePort ();
} else {
// Throw if result != ccNoError.
ThrowIfIPCError_ (err, result);
// Server is running and we got a change time. Remember it.
UpdateStateChangedTimeFromServer (changeTime);
}
}
return GetServerStateChangedTime ();
}
CCIUniqueID
CCIContextDataMachIPCStub::OpenCCache (
const std::string& inCCacheName) {
CCacheID ccache;
CCIResult result;
mach_port_t port = GetPortNoLaunch ();
if (port == MACH_PORT_NULL) {
// No server running, so no ccaches to find
ThrowIfIPCError_ (KERN_SUCCESS, ccErrCCacheNotFound);
} else {
kern_return_t err = ContextIPC_OpenCCache (port, GetContextID ().object, inCCacheName.c_str (), inCCacheName.length (), &ccache, &result);
if (err != KERN_SUCCESS) {
// Server died, no ccaches
InvalidatePort ();
ThrowIfIPCError_ (KERN_SUCCESS, ccErrCCacheNotFound);
} else {
ThrowIfIPCError_ (err, result);
}
}
return ccache;
}
CCIUniqueID
CCIContextDataMachIPCStub::OpenDefaultCCache () {
CCacheID ccache;
CCIResult result;
mach_port_t port = GetPortNoLaunch ();
if (port == MACH_PORT_NULL) {
// No server running, so no default ccache to find
ThrowIfIPCError_ (KERN_SUCCESS, ccErrCCacheNotFound);
} else {
kern_return_t err = ContextIPC_OpenDefaultCCache (port, GetContextID ().object, &ccache, &result);
if (err != KERN_SUCCESS) {
// Server died, no default ccache
InvalidatePort ();
ThrowIfIPCError_ (KERN_SUCCESS, ccErrCCacheNotFound);
} else {
ThrowIfIPCError_ (err, result);
}
}
return ccache;
}
std::string
CCIContextDataMachIPCStub::GetDefaultCCacheName () {
CCIMachIPCBuffer <char> buffer;
CCIResult result;
mach_port_t port = GetPortNoLaunch ();
if (port == MACH_PORT_NULL) {
// No server running, so just return what the server's inital default cache will be
return std::string (kInitialDefaultCCacheName);
} else {
kern_return_t err = ContextIPC_GetDefaultCCacheName (port, GetContextID ().object, &buffer.Data (), &buffer.Size (), &result);
if (err != KERN_SUCCESS) {
// Server died, return what default name would be
InvalidatePort ();
return std::string (kInitialDefaultCCacheName);
} else {
ThrowIfIPCError_ (err, result);
}
}
return std::string (buffer.Data (), buffer.Count ());
}
CCIUniqueID
CCIContextDataMachIPCStub::CreateCCache (
const std::string& inName,
CCIUInt32 inVersion,
const std::string& inPrincipal) {
CCacheID ccache;
CCIResult result;
kern_return_t err = ContextIPC_CreateCCache (GetPort (), GetContextID ().object, inName.c_str (), inName.length (), inVersion, inPrincipal.c_str (), inPrincipal.length (), &ccache, &result);
ThrowIfIPCError_ (err, result);
return ccache;
}
CCIUniqueID
CCIContextDataMachIPCStub::CreateDefaultCCache (
CCIUInt32 inVersion,
const std::string& inPrincipal) {
CCacheID ccache;
CCIResult result;
kern_return_t err = ContextIPC_CreateDefaultCCache (GetPort (), GetContextID ().object, inVersion, inPrincipal.c_str (), inPrincipal.length (), &ccache, &result);
ThrowIfIPCError_ (err, result);
return ccache;
}
CCIUniqueID
CCIContextDataMachIPCStub::CreateNewCCache (
CCIUInt32 inVersion,
const std::string& inPrincipal) {
CCacheID ccache;
CCIResult result;
kern_return_t err = ContextIPC_CreateNewCCache (GetPort (), GetContextID ().object, inVersion, inPrincipal.c_str (), inPrincipal.length (), &ccache, &result);
ThrowIfIPCError_ (err, result);
return ccache;
}
void CCIContextDataMachIPCStub::GetCCacheIDs (
std::vector <CCIObjectID>& outCCacheIDs) const {
CCIMachIPCBuffer <CCacheID> buffer;
CCIResult result;
mach_port_t port = GetPortNoLaunch ();
if (port == MACH_PORT_NULL) {
// No server running, so return an empty list
outCCacheIDs.resize (0);
} else {
kern_return_t err = ContextIPC_GetCCacheIDs (GetPort (), GetContextID ().object, &buffer.Data (), &buffer.Size (), &result);
if (err != KERN_SUCCESS) {
// Server died, return empty list
InvalidatePort ();
outCCacheIDs.resize (0);
} else {
ThrowIfIPCError_ (err, result);
outCCacheIDs.resize (buffer.Count ());
for (CCIUInt32 i = 0; i < buffer.Count (); i++) {
outCCacheIDs [i] = buffer.Data () [i];
}
}
}
}
bool
CCIContextDataMachIPCStub::Compare (
const CCIContext& inCompareTo) const {
CCIUInt32 equal;
CCIResult result;
kern_return_t err = ContextIPC_Compare (GetPort (), GetContextID ().object, inCompareTo.GetContextID ().object, &equal, &result);
ThrowIfIPCError_ (err, result);
return (equal != 0);
}
CCIUniqueID
CCIContextDataMachIPCStub::GetGlobalContextID () const
{
ContextID context;
CCIResult result;
mach_port_t port = GetPortNoLaunch (); // Not GetPort () or we will loop
if (port == MACH_PORT_NULL) {
// No server running so return the default context ID.
// When the server is launched later we will pick up the context id from it then
context = 0;
} else {
kern_return_t err = ContextIPC_GetGlobalContextID (port, &context, &result);
if (err != KERN_SUCCESS) {
InvalidatePort ();
context = 0;
} else {
ThrowIfIPCError_ (err, result);
}
}
return context;
}
mach_port_t
CCIContextDataMachIPCStub::GetPort () const
{
pid_t lastServerPID = GetLastServerPID (); // Note: get this first since GetPort may update it.
mach_port_t port = CCIMachIPCStub::GetPort ();
pid_t newServerPID = CCIMachIPCStub::GetServerPID (port);
//dprintf ("%s(): port: %x / lastServerPID: %d / newServerPID: %d", __FUNCTION__, port, lastServerPID, newServerPID);
if ((port != MACH_PORT_NULL) && (lastServerPID != newServerPID)) {
// A new server: remember the context id:
CCIUniqueID contextID = GetGlobalContextID ();
dprintf ("%s(): got new context id %d", __FUNCTION__, contextID.object);
SetContextID (contextID);
}
return port;
}
mach_port_t
CCIContextDataMachIPCStub::GetPortNoLaunch () const
{
pid_t lastServerPID = GetLastServerPID (); // Note: get this first since GetPortNoLaunch may update it.
mach_port_t port = CCIMachIPCStub::GetPortNoLaunch ();
pid_t newServerPID = CCIMachIPCStub::GetServerPID (port);
//dprintf ("%s(): port: %d / lastServerPID: %d / newServerPID: %d", __FUNCTION__, port, lastServerPID, newServerPID);
if ((port != MACH_PORT_NULL) && (lastServerPID != newServerPID)) {
// A new server: remember the context id:
CCIUniqueID contextID = GetGlobalContextID ();
dprintf ("%s(): got new context id %d", __FUNCTION__, contextID.object);
SetContextID (contextID);
}
return port;
}
CCILockID
CCIContextDataMachIPCStub::Lock () {
#warning CCIContextDataMachIPCStub::Lock() not implemented
return 0;
}
void
CCIContextDataMachIPCStub::Unlock (
CCILockID inLock) {
#warning CCIContextDataMachIPCStub::Unlock() not implemented
}