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 |