Beispiel #1
0
/* 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;
}
Beispiel #2
0
/* 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;
}