/* virtual */ SysStatus MemTrans::_swapHandle(ObjectHandle callerMT, //Caller's MT ObjectHandle callerFR, //Caller's FR uval callerSize, //Size of region uval& sizeRemote, ObjectHandle &remoteFR, __XHANDLE xhandle, __CALLER_PID pid) { ClientData *cd = clnt(xhandle); tassertMsg(cd,"No clientData defined\n"); uval addr=0; SysStatus rc = 0; rc = StubRegionDefault::_CreateFixedLenExt( addr, callerSize, 0, callerFR, 0, AccessMode::writeUserWriteSup, 0, RegionType::K42Region); ObjectHandle frOH; if (_SUCCESS(rc)) { cd->init(callerFR, callerMT, addr, callerSize); rc = localFR._giveAccess(frOH, pid); } else { return rc; } remoteFR = frOH; sizeRemote = callerSize; return rc; }
/* virtual */ SysStatus MemTrans::init(ProcessID partner, XHandle &remoteX, uval size, MTEvents *handler) { debug = 0; SysStatus rc = 0; CObjRootSingleRep::Create(this); uval addr = 0; ObjectHandle myFRInt; ObjectHandle localOH; ObjectHandle remoteOH; localSize = size; //Ref count is 1 --- for whoever created this object refCount = 1; allocLock.init(); cbs = handler; // Lock out allocations until we're done initialization AutoLock<LockType> al(&allocLock); // Give other process access to this MT rc = giveAccessByServer(localOH, partner); _IF_FAILURE_RET(rc); remoteX = localOH.xhandle(); usedPages.append(new PageUse(localSize/PAGE_SIZE, 0)); // Create FR for local-side memory area (that will be exported) rc = StubFRComputation::_Create(myFRInt); _IF_FAILURE_RET_VERBOSE(rc); localFR.setOH(myFRInt); rc = StubRegionDefault::_CreateFixedLenExt( localBase, localSize, 0, myFRInt, 0, AccessMode::writeUserWriteSup, 0, RegionType::K42Region); _IF_FAILURE_RET_VERBOSE(rc); // Create an OH to a global object in the other process and // look for a matching MemTrans there // But, if this is the kernel, we never attempt this --- // Can't trust the other process to not block us on this // So we always wait for the other process to call _swapHandle if (DREFGOBJ(TheProcessRef)->getPID() == _KERNEL_PID) { return 0; } ObjectHandle SMTDB; SMTDB.initWithPID(partner,XHANDLE_MAKE_NOSEQNO(CObjGlobals::ProcessIndex)); StubProcessClient stubPC(StubObj::UNINITIALIZED); stubPC.setOH(SMTDB); rc = stubPC._getMemTrans(remoteOH, key); if (_SUCCESS(rc)) { StubMemTrans remote(StubObj::UNINITIALIZED); remote.setOH(remoteOH); uval remoteSize; ObjectHandle frOH; // Give access to this area to the other process // FIXME: give access for read only ObjectHandle myFRExt; rc = localFR._giveAccess(myFRExt, partner); _IF_FAILURE_RET_VERBOSE(rc); // Give remote process OH's to our FR and MT rc = remote._swapHandle(localOH, myFRExt, localSize, remoteSize, frOH); _IF_FAILURE_RET_VERBOSE(rc); rc = StubRegionDefault::_CreateFixedLenExt( addr, remoteSize, 0, frOH, 0, AccessMode::writeUserWriteSup, 0, RegionType::K42Region); _IF_FAILURE_RET_VERBOSE(rc); ClientData *cd = clnt(remoteX); cd->init(frOH, remoteOH, addr, remoteSize); remote._completeInit(); } return 0; }