1. 程式人生 > >gecko.dom.ipc程序通訊:PContent,PNuwa,Process三系分析

gecko.dom.ipc程序通訊:PContent,PNuwa,Process三系分析

gecko/dom/ipc/此模組承擔的工作是什麼:

dom/ipc如下,每個ipdl檔案對應3個頭檔案,

ipdl的生成檔案,

幾個類的繼承關係

兩個系列:PContent  和PNuwa,Process系,三個系

(1)Process 系是對前面兩個系的使用,自己寫的

gecko/ipc/chromium/src/chrome/common/child_process.h

// Base class for child processes of the browser process (i.e. renderer and // plugin host). This is a singleton object for each child process. class ChildProcess {  public:   // Child processes should have an object that derives from this class.  The   // constructor will return once ChildThread has started.   explicit ChildProcess(ChildThread* child_thread);   virtual ~ChildProcess();

  // Getter for this process' main thread.   ChildThread* child_thread() { return child_thread_.get(); }

  // A global event object that is signalled when the main thread's message   // loop exits

gecko/ipc/glue/ProcessChild.h

#include "base/message_loop.h" #include "base/process.h"

#include "chrome/common/child_process.h"

// ProcessChild is the base class for all subprocesses of the main // browser process.  Its code runs on the thread that started in // main().

namespace mozilla { namespace ipc {

class ProcessChild : public ChildProcess {

protected:   typedef base::ProcessId ProcessId;

public:   explicit ProcessChild(ProcessId aParentPid);   virtual ~ProcessChild(); 。。。

gecko/dom/ipc/ContentProcess.h

/**  * ContentProcess is a singleton on the content process which represents  * the main thread where tab instances live.  */ class ContentProcess : public mozilla::ipc::ProcessChild {     typedef mozilla::ipc::ProcessChild ProcessChild;

public:     explicit ContentProcess(ProcessId aParentPid)         : ProcessChild(aParentPid)     { }

    ~ContentProcess()     { }

    virtual bool Init() override;     virtual void CleanUp() override;

    void SetAppDir(const nsACString& aPath);

private:     ContentChild mContent;     mozilla::ipc::ScopedXREEmbed mXREEmbed;

    DISALLOW_EVIL_CONSTRUCTORS(ContentProcess); };

gecko/ipc/glue/ProcessChild.cpp

建立例項時將同時建立io子執行緒,開啟uimessageloop獲取當前的訊息迴圈佇列,傳入父id, ProcessChild::ProcessChild(ProcessId aParentPid)   : ChildProcess(new IOThreadChild())   , mUILoop(MessageLoop::current())   , mParentPid(aParentPid) { P_LOGI(SEPARATOR_LINE); P_LOGI("init this func with-- ProcessChild::ProcessChild(ProcessId aParentPid:%d) : ChildProcess(new IOThreadChild()) , mUILoop(MessageLoop::current()) , mParentPid(aParentPidi:%d) ---", (int)aParentPid, (int)aParentPid); P_LOGI("call -- MOZ_ASSERT(mUILoop, 'UILoop should be created by now'); --->");   MOZ_ASSERT(mUILoop, "UILoop should be created by now");   MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");   gProcessChild = this; }

繼承關係:

ChildProcess > ProcessChild >  ContentProcess具體它負責什麼?全是自己寫的,,

PContent.ipdl生成三個檔案:

objdir-gecko/ipc/ipdl/_ipdlheaders/mozilla/dom/PContent.h

objdir-gecko/ipc/ipdl/_ipdlheaders/mozilla/dom/PContentParent.h

objdir-gecko/ipc/ipdl/_ipdlheaders/mozilla/dom/PContentChild.h

dom/ipc/PContent.ipdl包羅永珍,總體說負責了什麼?不確定,像ipdl的實現,不對。。。PContent.ipdl大家都要包含(include)說不清它到底幹嘛了,不用管,總之被另外兩個自動生成的標頭檔案繼承實現了些什麼,之後,那兩個標頭檔案分別被手動寫的實現檔案繼承。

.。。。

  * cleaned up.      */     async NotifyPresentationReceiverCleanUp(nsString aSessionId);

parent:     /**      * Tell the content process some attributes of itself.  This is      * among the first information queried by content processes after      * startup.  (The message is sync to allow the content process to      * control when it receives the information.)      *      * |id| is a unique ID among all subprocesses.  When |isForApp &&      * isForBrowser|, we're loading <browser> for an app.  When      * |isForBrowser|, we're loading <browser>.  When |!isForApp &&      * !isForBrowser|, we're probably loading <xul:browser remote>.      *      * Keep the return values in sync with PBrowser()!      */     sync GetProcessAttributes()         returns (ContentParentId cpId, bool isForApp, bool isForBrowser);     sync GetXPCOMProcessAttributes()         returns (bool isOffline, bool isConnected, bool isLangRTL, nsString[] dictionaries,                  ClipboardCapabilities clipboardCaps,                  DomainPolicyClone domainPolicy,                  StructuredCloneData initialData);

    sync CreateChildProcess(IPCTabContext context,                             ProcessPriority priority,                             TabId openerTabId)         returns (ContentParentId cpId, bool isForApp, bool isForBrowser, TabId tabId);     sync BridgeToChildProcess(ContentParentId cpId);

    async CreateGMPService();     sync GetGMPPluginVersionForAPI(nsCString api, nsCString[] tags)         returns (bool hasPlugin, nsCString version);     sync IsGMPPresentOnDisk(nsString keySystem, nsCString version)         returns (bool isPresent, nsCString message);

    /**      * This call connects the content process to a plugin process. While this      * call runs, a new PluginModuleParent will be created in the ContentChild      * via bridging. The corresponding PluginModuleChild will live in the plugin      * process.      */     sync LoadPlugin(uint32_t aPluginId) returns (nsresult aResult, uint32_t aRunID);

    /**      * This call is used by asynchronous plugin instantiation to notify the    

./ipc/ipdl/_ipdlheaders/mozilla/dom/PContent.h

//----------------------------------------------------------------------------- // Code common to PContentChild and PContentParent // namespace mozilla { namespace dom { namespace PContent {

enum State {     __Dead,     __Null,     __Error,     __Dying,     __Start = __Null };

enum MessageType {     PContentStart = PContentMsgStart << 16,     Msg_PBrowserConstructor__ID,     Reply_PBrowserConstructor__ID,     Msg_PBlobConstructor__ID,     Reply_PBlobConstructor__ID,     Msg_PFileDescriptorSetConstructor__ID,     Reply_PFileDescriptorSetConstructor__ID,     Msg_PWeb

1.3w+行,,,,很多message 型別,很多類,,,宣告等

PContent.ipdl

./ipc/ipdl/_ipdlheaders/mozilla/dom/PContentChild.h

class PContentChild :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>,     public mozilla::ipc::IToplevelProtocol {     friend class mozilla::media::PMediaChild;

dom/ipc/ContentChild.h

class ContentChild final : public PContentChild                          , public nsIWindowProvider                          , public nsIContentChild {    

PContentChild > ContentChild

PContent.ipdl

./ipc/ipdl/_ipdlheaders/mozilla/dom/PContentParent.h

namespace mozilla { namespace dom {

class PContentParent :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>,     public mozilla::ipc::IToplevelProtocol {     friend class mozilla::media::PMediaParent;

    friend class mozilla::jsipc::PJavaScriptParent;

dom/ipc/ContentParent.h

class ContentParent final : public PContentParent                           , public nsIContentParent                           , public nsIObserver                           , public nsIDOMGeoPositionCallback                           , public nsIDOMGeoPositionErrorCallback                           , public mozilla::LinkedListElement<ContentParent> {     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;     type

亂七八糟。。。

ContentParnet.h

ContentChild.h

ContentProces.h是PContent.ipdl生成檔案的繼承後的實現?錯,對了一部分。它只用了PContentChild.h部分,所以在Nuwa一側?

關係,

(1)

PContent.ipdl

|

./ipc/ipdl/_ipdlheaders/mozilla/dom/PContentChild.h

#include "mozilla/dom/PContent.h" #ifdef DEBUG #include "prenv.h" #endif // DEBUG #include "base/id_map.h" #include "mozilla/ipc/MessageChannel.h"

class PContentChild :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>,     public mozilla::ipc::IToplevelProtocol {     friend class mozilla::media::PMediaChild;

dom/ipc/ContentChild.h

#include "mozilla/Attributes.h" #include "mozilla/dom/ContentBridgeParent.h" #include "mozilla/dom/nsIContentChild.h" #include "mozilla/dom/PBrowserOrId.h" #include "mozilla/dom/PContentChild.h" #include "nsHashKeys.h" #include "nsIObserver.h" #include "nsTHashtable.h"

#include "nsWeakPtr.h" #include "nsIWindowProvider.h"

class ContentChild final : public PContentChild                          , public nsIWindowProvider                          , public nsIContentChild {     typedef mozilla::dom::ClonedMessageData ClonedMessageData;     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;     typedef mozilla::ipc::PFileDescriptorSetChild PFileDescriptorSetChild;     typedef mozilla::ipc::URIParams URIParams;

 並列

gecko/ipc/glue/ProcessChild.h 單獨用

#include "base/message_loop.h" #include "base/process.h"

#include "chrome/common/child_process.h"

// ProcessChild is the base class for all subprocesses of the main // browser process.  Its code runs on the thread that started in // main().

namespace mozilla { namespace ipc {

class ProcessChild : public ChildProcess { protected:   typedef base::ProcessId ProcessId;

public:   explicit ProcessChild(ProcessId aParentPid);   virtual ~ProcessChild();

  virtual bool Init() = 0;   virtual void CleanUp()   { }

  static MessageLoop* message_loop() {     return gProcessChild->mUILoop;   }

protected:   static ProcessChild* current() {     return gProcessChild;   }

  ProcessId ParentPid() {     return mParentPid;   }

private:   static ProcessChild* gProcessChild;

  MessageLoop* mUILoop;   ProcessId mParentPid;

  DISALLOW_EVIL_CONSTRUCTORS(ProcessChild); };

} // namespace ipc } // namespace mozilla

gecko/dom/ipc/ContentProces.h如下

#include "mozilla/ipc/ProcessChild.h" #include "mozilla/ipc/ScopedXREEmbed.h" #include "ContentChild.h"

namespace mozilla { namespace dom {

/**  * ContentProcess is a singleton on the content process which represents  * the main thread where tab instances live.  */ class ContentProcess : public mozilla::ipc::ProcessChild {     typedef mozilla::ipc::ProcessChild ProcessChild;

public:     explicit ContentProcess(ProcessId aParentPid)         : ProcessChild(aParentPid)     { }

    ~ContentProcess()     { }

    virtual bool Init() override;     virtual void CleanUp() override;

ContentProces.h是對ProcessChild.h,ContentChild.h"等的統合使用。

ContentProcess最後把Child支系的全收了,在此處進行大綜合(即使用)。

目的是什麼?gecko/ipc/glue/ProcessChild.h的作用是messageloop,獲取當前執行緒ioloop等

ipdl的本質工作即是讓parent端與child端能通訊。相互搞些事情。

(2)

PContent.ipdl

|

./ipc/ipdl/_ipdlheaders/mozilla/dom/PContentParent.h

#include "mozilla/dom/PContent.h" #ifdef DEBUG #include "prenv.h" #endif // DEBUG #include "base/id_map.h" #include "mozilla/ipc/MessageChannel.h"

c

namespace mozilla { namespace dom {

class PContentParent :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>,     public mozilla::ipc::IToplevelProtocol {     friend class mozilla::media::PMediaParent;

    friend class mozilla::jsipc::PJavaScriptParent;

dom/ipc/ContentParent.h

#include "mozilla/dom/NuwaParent.h" #include "mozilla/dom/PContentParent.h" #include "mozilla/dom/nsIContentParent.h" #include "mozilla/ipc/GeckoChildProcessHost.h" #include "mozilla/Attributes.h" #include "mozilla/FileUtils.h" #include "mozilla/HalTypes.h" #include "mozilla/LinkedList.h" #include "mozilla/StaticPtr.h" #include "mozilla/UniquePtr.h"

#include "nsDataHashtable.h" #include "nsFrameMessageManager.h" #include "nsHashKeys.h" #include "nsIObserver.h" #include "nsIThreadInternal.h" #include "nsIDOMGeoPositionCallback.h" #include "nsIDOMGeoPositionErrorCallback.h" #include "PermissionMessageUtils.h" #include "DriverCrashGuard.h"

class ContentParent final : public PContentParent                           , public nsIContentParent                           , public nsIObserver                           , public nsIDOMGeoPositionCallback                           , public nsIDOMGeoPositionErrorCallback                           , public mozilla::LinkedListElement<ContentParent> {     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;     typedef mozilla::ipc::PFileDescriptorSetParent PFileDescriptorSetParent;     typedef mozilla::ipc::TestShellParent TestShellParent;     typedef mozilla::ipc::URIParams URIParams;     typedef mozilla::ipc::PrincipalInfo PrincipalInfo;     typedef mozilla::dom::ClonedMessageData ClonedMessageData;

public: #ifdef MOZ_NUWA_PROCESS     static int32_t NuwaPid() {         return sNuwaPid;     }

    static bool IsNuwaReady() {         return sNuwaReady;     } #endif     virtual bool IsContentParent() override { return true; }     /**

ContentParnet.h是對PNuwa系,PContent系中的引用,換句話說就是使用。,沒錯誤!

PNuwa.ipdl系,生成三個標頭檔案,其繼承關係如下:

PNuwa.h       

PNuwaParent.h

PNuwaChild.h  

在NuwaParent.h NuwaChild.h裡面來實現各介面的功能。

gecko/dom/ipc/PNuwa.ipdl

sync protocol PNuwa {   manager PBackground;

child:   // Ask the Nuwa process to create a new child process.   async Fork();

  // This message will be sent to non-Nuwa process, or to Nuwa process during   // test.   async __delete__();

parent:   async NotifyReady();   sync AddNewProcess(uint32_t pid, ProtocolFdMapping[] aFds); };

 ./ipc/ipdl/_ipdlheaders/mozilla/dom/PNuwa.h 幾個訊息型別的類,其他ipdl檔案也一樣

  ▶ MessageType : enum       ▶ State : enum       ▶ Msg_AddNewProcess : class       ▶ Msg_Fork : class       ▶ Msg_NotifyReady : class       ▶ Msg___delete__ : class       ▶ Reply_AddNewProcess : class       ▶ Reply___delete__ : class

(1)

./ipc/ipdl/_ipdlheaders/mozilla/dom/PNuwaChild.h

#include "mozilla/dom/PNuwa.h" #ifdef DEBUG #include "prenv.h" #endif // DEBUG #include "base/id_map.h" #include "mozilla/ipc/MessageChannel.h"

class PNuwaChild :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol> {     friend class mozilla::ipc::PBackgroundChild;

protected:     typedef mozilla::ipc::ActorHandle ActorHandle;.

。。。

    virtual bool    RecvFork() = 0;     virtual bool    Recv__delete__();

    virtual void    ActorDestroy(ActorDestroyReason aWhy);

public:

。。。。

public:     MOZ_IMPLICIT PNuwaChild();

    virtual ~PNuwaChild();

    PBackgroundChild*     Manager() const;

    PNuwa::State     state();

    bool    SendNotifyReady();

    bool    SendAddNewProcess(             const uint32_t& pid,             const nsTArray<ProtocolFdMapping>& aFds);

    virtual int32_t     Registe。。。

gecko/dom/ipc/NuwaChild.h

#include "mozilla/Assertions.h" #include "mozilla/dom/PNuwaChild.h" #include "nsThreadUtils.h"

namespace mozilla { namespace dom { class NuwaChild: public mozilla::dom::PNuwaChild { public:   virtual bool RecvFork() override;

  virtual void ActorDestroy(ActorDestroyReason aWhy) override   { }

  static NuwaChild* GetSingleton();

private:   static NuwaChild* sSingleton; };

} // namespace dom } // namespace mozilla

(2)

./ipc/ipdl/_ipdlheaders/mozilla/dom/PNuwaParent.h

#include "mozilla/dom/PNuwa.h" #ifdef DEBUG #include "prenv.h" #endif // DEBUG #include "base/id_map.h" #include "mozilla/ipc/MessageChannel.h"

class PNuwaParent :     public mozilla::ipc::IProtocol,     protected mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol> {     friend class mozilla::ipc::PBackgroundParent;

protected:     typedef mozilla::ipc::ActorHandle ActorHandle;     typedef mo

gecko/dom/ipc/NuwaParent .h對介面進行實現

#include "base/message_loop.h" #include "mozilla/dom/PNuwaParent.h" #include "...

namespace mozilla { namespace dom {

class ContentParent;

class NuwaParent : public mozilla::dom::PNuwaParent { public:   explicit NuwaParent();

  // Called on the main thread.   bool ForkNewProcess(uint32_t& aPid,                       UniquePtr<nsTArray<ProtocolFdMapping>>&& aFds,                       bool aBlocking);

  // Called on the background thread.   bool ActorConstructed();

  // Both the worker thread and the main thread hold a ref to this.   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NuwaParent)

  // Functions to be invoked by the manager of this actor to alloc/dealloc the   // actor.   static NuwaParent* Alloc();

...

protected:   virtual ~NuwaParent();

  virtual bool RecvNotifyReady() override;   virtual bool RecvAddNewProcess(const uint32_t& aPid,                                  nsTArray<ProtocolFdMapping>&& aFds) override;   virtual mozilla::ipc::IProtocol*   CloneProtocol(Channel* aChannel,                 ProtocolCloneContext* aCtx) override;

  virtual void ActorDestroy(ActorDestroyReason aWhy) override;

private:

... };

} // namespace dom } // namespace mozilla