Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Private Member Functions | Private Attributes
DConnectStub Class Reference
Collaboration diagram for DConnectStub:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS DConnectStub (nsIInterfaceInfo *aIInfo, DConAddr aInstance, PRUint32 aPeerID)
NS_IMETHOD GetInterfaceInfo (nsIInterfaceInfo **aInfo)
NS_IMETHOD CallMethod (PRUint16 aMethodIndex, const nsXPTMethodInfo *aInfo, nsXPTCMiniVariant *aParams)
DConAddr Instance ()
PRUint32 PeerID ()

Private Member Functions

NS_HIDDEN ~DConnectStub ()
 NS_HIDDEN_ (DConnectStub *) FindStubSupportingIID(const nsID &aIID)
 NS_HIDDEN_ (PRBool) SupportsIID(const nsID &aIID)

Private Attributes

nsCOMPtr< nsIInterfaceInfomIInfo
nsVoidArray mChildren
DConnectStubmMaster
DConAddr mInstance
PRUint32 mPeerID

Detailed Description

Definition at line 762 of file ipcDConnectService.cpp.


Constructor & Destructor Documentation

NS_DECL_ISUPPORTS DConnectStub::DConnectStub ( nsIInterfaceInfo aIInfo,
DConAddr  aInstance,
PRUint32  aPeerID 
) [inline]

Definition at line 767 of file ipcDConnectService.cpp.

    : mIInfo(aIInfo)
    , mMaster(nsnull)
    , mInstance(aInstance)
    , mPeerID(aPeerID)
    {}

Here is the caller graph for this function:

Definition at line 904 of file ipcDConnectService.cpp.

{
  // destroying stub, notify peer that we have released our reference

  nsresult rv;

  DConnectRelease msg;
  msg.opcode_major = DCON_OP_RELEASE;
  msg.opcode_minor = 0;
  msg.instance = mInstance;

  // fire off asynchronously... we don't expect any response to this message.
  rv = IPC_SendMessage(mPeerID, kDConnectTargetID,
                       (const PRUint8 *) &msg, sizeof(msg));
  if (NS_FAILED(rv))
    NS_WARNING("failed to send RELEASE event");

  if (!mMaster)
  {
    // delete each child stub
    for (PRInt32 i=0; i<mChildren.Count(); ++i)
      delete (DConnectStub *) mChildren[i];
  }
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 1091 of file ipcDConnectService.cpp.

{
  nsresult rv;

  LOG(("DConnectStub::CallMethod [methodIndex=%hu]\n", aMethodIndex));

  // dump arguments

  PRUint8 i, paramCount = aInfo->GetParamCount();

  LOG(("  name=%s\n", aInfo->GetName()));
  LOG(("  param-count=%u\n", (PRUint32) paramCount));

  ipcMessageWriter writer(16 * paramCount);

  // INVOKE message header
  DConnectInvoke invoke;
  invoke.opcode_major = DCON_OP_INVOKE;
  invoke.opcode_minor = 0;
  invoke.request_index = NewRequestIndex();
  invoke.instance = mInstance;
  invoke.method_index = aMethodIndex;

  writer.PutBytes(&invoke, sizeof(invoke));

  // list of wrappers that get created during parameter serialization.  if we
  // are unable to send the INVOKE message, then we'll clean these up.
  nsVoidArray wrappers;

  for (i=0; i<paramCount; ++i)
  {
    const nsXPTParamInfo &paramInfo = aInfo->GetParam(i);

    if (paramInfo.IsIn() && !paramInfo.IsDipper())
    {
      const nsXPTType &type = paramInfo.GetType();

      if (type.IsInterfacePointer())
      {
        nsID iid;
        rv = gDConnect->GetIIDForMethodParam(mIInfo, aInfo, paramInfo, type,
                                             aMethodIndex, i, aParams, PR_FALSE, iid);
        if (NS_SUCCEEDED(rv))
          rv = SerializeInterfaceParam(writer, mPeerID, iid, type, aParams[i], wrappers);
      }
      else
        rv = SerializeParam(writer, type, aParams[i]);

      if (NS_FAILED(rv))
        return rv;
    }
  }

  rv = IPC_SendMessage(mPeerID, kDConnectTargetID,
                       writer.GetBuffer(),
                       writer.GetSize());
  if (NS_FAILED(rv))
  {
    // INVOKE message wasn't delivered; clean up wrappers
    DeleteWrappers(wrappers);
    return rv;
  }

  // now, we wait for the method call to complete.  during that time, it's
  // possible that we'll receive other method call requests.  we'll process
  // those while waiting for out method call to complete.  it's critical that
  // we do so since those other method calls might need to complete before
  // out method call can complete!

  DConnectInvokeCompletion completion(&invoke);

  do
  {
    rv = IPC_WaitMessage(mPeerID, kDConnectTargetID, &completion,
                         DCON_WAIT_TIMEOUT);
    if (NS_FAILED(rv))
    {
      // INVOKE message wasn't received; clean up wrappers
      DeleteWrappers(wrappers);
      return rv;
    }
  }
  while (completion.IsPending());

  rv = completion.GetResult();
  if (NS_SUCCEEDED(rv) && completion.ParamsLen() > 0)
  {
    ipcMessageReader reader(completion.Params(), completion.ParamsLen());

    PRUint8 i;

    // handle out-params and retvals: DCON_OP_INVOKE_REPLY has the data
    for (i=0; i<paramCount; ++i)
    {
      const nsXPTParamInfo &paramInfo = aInfo->GetParam(i);

      if (paramInfo.IsOut() || paramInfo.IsRetval())
        DeserializeResult(reader, paramInfo.GetType(), aParams[i]);
    }

    // fixup any interface pointers using a second pass so we can properly
    // handle INTERFACE_IS referencing an IID that is an out param!
    for (i=0; i<paramCount; ++i)
    {
      const nsXPTParamInfo &paramInfo = aInfo->GetParam(i);
      if (aParams[i].val.p && (paramInfo.IsOut() || paramInfo.IsRetval()))
      {
        const nsXPTType &type = paramInfo.GetType();
        if (type.IsInterfacePointer())
        {
          PtrBits bits = (PtrBits) *((void **) aParams[i].val.p);
          if (bits & 0x1)
          {
            *((void **) aParams[i].val.p) = (void *) (bits & ~0x1);

            nsID iid;
            rv = gDConnect->GetIIDForMethodParam(mIInfo, aInfo, paramInfo, type,
                                                 aMethodIndex, i, aParams, PR_FALSE, iid);
            if (NS_SUCCEEDED(rv))
            {
              DConnectStub *stub;
              void **pptr = (void **) aParams[i].val.p;
              rv = CreateStub(iid, mPeerID, (DConAddr) *pptr, &stub);
              if (NS_SUCCEEDED(rv))
                *((nsISupports **) aParams[i].val.p) = stub;
            }
          }
          else if (bits)
          {
            // pointer is to one of our instance wrappers.

            DConnectInstance *wrapper = (DConnectInstance *) aParams[i].val.p;
            *((void **) aParams[i].val.p) = wrapper->RealInstance();
          }
          else
          {
            *((void **) aParams[i].val.p) = nsnull;
          }
        }
      }
    }
  }

  return rv;
}

Here is the call graph for this function:

Definition at line 1084 of file ipcDConnectService.cpp.

{
  NS_ADDREF(*aInfo = mIInfo);
  return NS_OK;
}

Here is the call graph for this function:

Definition at line 785 of file ipcDConnectService.cpp.

{ return mInstance; }
DConnectStub::NS_HIDDEN_ ( DConnectStub ) const [private]
DConnectStub::NS_HIDDEN_ ( PRBool  ) const [private]

Definition at line 786 of file ipcDConnectService.cpp.

{ return mPeerID; }

Member Data Documentation

Definition at line 800 of file ipcDConnectService.cpp.

Definition at line 798 of file ipcDConnectService.cpp.

Definition at line 804 of file ipcDConnectService.cpp.

Definition at line 801 of file ipcDConnectService.cpp.

Definition at line 807 of file ipcDConnectService.cpp.


The documentation for this class was generated from the following file: