当前位置: 首页 > news >正文

网站开发语言啥意思网站统计

网站开发语言啥意思,网站统计,手提电脑做网站服务器,小程序怎么做成链接关于mojo binding的官方文档为mojo docs。 由于比较复杂,这里只做简单源码分析。 我们知道要实现rpc,必须实现客户端和服务端。 mojo 实现了一套领域语言,通过领域语言描述接口和数据, 再通过特有编译器编译成c代码。 这个过程会…

关于mojo binding的官方文档为mojo docs。 由于比较复杂,这里只做简单源码分析。

我们知道要实现rpc,必须实现客户端和服务端。 mojo 实现了一套领域语言,通过领域语言描述接口和数据, 再通过特有编译器编译成c++代码。 这个过程会生成Mojo对象, 我们以content/common/child_process.mojom 为例子来分析。


interface ChildProcess {......// Requests that the process bind a receiving pipe targeting the service// interface named by |receiver|.//// TODO(crbug.com/977637): Rename this to |RunService()| once the above method// is removed.BindServiceInterface(mojo_base.mojom.GenericPendingReceiver receiver);// Requests that the process bind a receiving pipe targeting the interface// named by |receiver|. Unlike |BindServiceInterface()| this may be used to// bind arbitrary interfaces on many different types of child processes.// Calls to this method generally end up in// |ChildThreadImpl::OnBindReceiver()|.//// Whether or not the interface type encapsulated by |receiver| is supported// depends on the process type and potentially on the Content embedder.BindReceiver(mojo_base.mojom.GenericPendingReceiver receiver);......
};

我们删除一些接口,总体定义如下。生成带c++代码如下。
out/Default/gen/content/common/child_process.mojom.h

class CONTENT_EXPORT ChildProcess: public ChildProcessInterfaceBase {public:......// 接口的名字static const char Name_[];// 方法表,用于将消息序号转化为处理函数static IPCStableHashFunction MessageToMethodInfo_(mojo::Message& message);// 方法名称表static const char* MessageToMethodName_(mojo::Message& message);// 协议版本static constexpr uint32_t Version_ = 0;static constexpr bool PassesAssociatedKinds_ = false;// 是否包含不可中断的方法static constexpr bool HasUninterruptableMethods_ = false;using Base_ = ChildProcessInterfaceBase;// 代理对象,用于客户端调用using Proxy_ = ChildProcessProxy;template <typename ImplRefTraits>// 用于指向服务端实现using Stub_ = ChildProcessStub<ImplRefTraits>;// 请求校验器using RequestValidator_ = ChildProcessRequestValidator;// 回复校验器using ResponseValidator_ = mojo::PassThroughFilter;// 方法版本列表enum MethodMinVersions : uint32_t {kProcessShutdownMinVersion = 0,kSetIPCLoggingEnabledMinVersion = 0,kGetBackgroundTracingAgentProviderMinVersion = 0,kEnableSystemTracingServiceMinVersion = 0,kCrashHungProcessMinVersion = 0,kRunServiceDeprecatedMinVersion = 0,kBindServiceInterfaceMinVersion = 0,kBindReceiverMinVersion = 0,kSetPseudonymizationSaltMinVersion = 0,};......// 下面是方法声明virtual ~ChildProcess() = default;......virtual void BindServiceInterface(::mojo::GenericPendingReceiver receiver) = 0;virtual void BindReceiver(::mojo::GenericPendingReceiver receiver) = 0;......
};

生成的c++ 类除了方法声明之外,还包括如下信息:

  • Name_接口名称
  • MessageToMethodInfo_: 方法表,通过收到的消息找到对应的rpc方法。
  • Proxy_ 代理对象,通过代理对象调用具体方法组装消息,发送给服务端。(包括方法名称,参数等,用于调用服务端对应方法)
  • Stub_ 用于描述服务端,指向服务端具体实现。
  • RequestValidator_ 请求校验。
  • ResponseValidator_ 响应校验。

通过官方文档我们知道通过Remote 调用服务端方法。 来看一下Remote 是如何实现的。
mojo/public/cpp/bindings/remote.h

 887 void ChildProcessProxy::BindServiceInterface(888     ::mojo::GenericPendingReceiver in_receiver) {889 #if BUILDFLAG(MOJO_TRACE_ENABLED)890   TRACE_EVENT1(891     "mojom", "Send content::mojom::ChildProcess::BindServiceInterface", "input_parameters",892     [&](perfetto::TracedValue context){893       auto dict = std::move(context).WriteDictionary();894       perfetto::WriteIntoTracedValueWithFallback(895            dict.AddItem("receiver"), in_receiver,896                         "<value of type ::mojo::GenericPendingReceiver>");897    });898 #endif899   const bool kExpectsResponse = false;900   const bool kIsSync = false;901   const bool kAllowInterrupt = true;902 903   const uint32_t kFlags =904       ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |905       ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |906       ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);907 908   mojo::Message message(909       internal::kChildProcess_BindServiceInterface_Name, kFlags, 0, 0, nullptr);910   mojo::internal::MessageFragment<911       ::content::mojom::internal::ChildProcess_BindServiceInterface_Params_Data> params(912           message);913   params.Allocate();914   mojo::internal::MessageFragment<915       typename decltype(params->receiver)::BaseType> receiver_fragment(916           params.message());917   mojo::internal::Serialize<::mojo_base::mojom::GenericPendingReceiverDataView>(918       in_receiver, receiver_fragment);919   params->receiver.Set(920       receiver_fragment.is_null() ? nullptr : receiver_fragment.data());921   MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(922       params->receiver.is_null(),923       mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,924       "null receiver in ChildProcess.BindServiceInterface request");925 926 #if defined(ENABLE_IPC_FUZZER)927   message.set_interface_name(ChildProcess::Name_);928   message.set_method_name("BindServiceInterface");929 #endif930   // This return value may be ignored as false implies the Connector has931   // encountered an error, which will be visible through other means.932   ::mojo::internal::SendMojoMessage(*receiver_, message);933 }

BindServiceInterface 的主要作用就是组装消息,然后发送。 这里908-909行创建Message的时候指定的消息名称为internal::kChildProcess_BindServiceInterface_Name, 用于指示服务端调用哪个方法。 这里932行receiver_ 持有一个portal,可以将数据写出去。

我们再看服务端怎么处理消息:

259 // Implements the mojom ChildProcess interface and lives on the IO thread.
260 class ChildThreadImpl::IOThreadState
261     : public base::RefCountedThreadSafe<IOThreadState>,
262       public mojom::ChildProcess {......
358 
359   void BindServiceInterface(mojo::GenericPendingReceiver receiver) override {
360     if (service_binder_)
361       service_binder_.Run(&receiver);
362 
363     if (receiver) {
364       main_thread_task_runner_->PostTask(
365           FROM_HERE, base::BindOnce(&ChildThreadImpl::BindServiceInterface,
366                                     weak_main_thread_, std::move(receiver)));
367     }
368   }
369 
370   void BindReceiver(mojo::GenericPendingReceiver receiver) override {
371     if (wait_for_interface_binders_) {
372       pending_binding_requests_.push_back(std::move(receiver));
373       return;
374     }
375 
376     if (interface_binders_.TryBind(&receiver))
377       return;
378 
379     main_thread_task_runner_->PostTask(
380         FROM_HERE, base::BindOnce(&ChildThreadImpl::OnBindReceiver,
381                                   weak_main_thread_, std::move(receiver)));
382   }
383 ......457   mojo::Receiver<mojom::ChildProcess> receiver_{this};
458 
459   // Binding requests which should be handled by |interface_binders|, but which
460   // have been queued because |allow_interface_binders_| is still |false|.
461   std::vector<mojo::GenericPendingReceiver> pending_binding_requests_;
462 };

ChildThreadImpl::IOThreadState 实现了mojom::ChildProcess接口。 它持有了一个receiver_对象, 该对象持有portal一端, 用于处理对端发送的消息。

我们具体来看 mojo::Receivermojom::ChildProcess 的实现。

template <typename Interface,typename ImplRefTraits = RawPtrImplRefTraits<Interface>>
class Receiver {
......explicit Receiver(ImplPointerType impl) : internal_state_(std::move(impl)) {}
......private:internal::BindingState<Interface, ImplRefTraits> internal_state_;
}

Receiver 的参数为ChildThreadImpl::IOThreadState实例。 然后初始化internal_state_变量。internal_state_类型展开宏之后为nternal::BindingState<mojom::ChildProcess, RawPtrImplRefTraitsmojom::ChildProcess> internal_state_。

template <typename Interface, typename ImplRefTraits>
class BindingState : public BindingStateBase {public:using ImplPointerType = typename ImplRefTraits::PointerType;explicit BindingState(ImplPointerType impl) {stub_.set_sink(std::move(impl));}......
}

这里stub_成员变量为 typename Interface::template Stub_ stub_;展开宏为
mojom::ChildProcess::Stub_ stub_, 也就是ChildProcessStub。 我们看一下它的实现以及set_sink 方法。
out/Default/gen/content/common/child_process.mojom.h


template <typename ImplRefTraits =mojo::RawPtrImplRefTraits<ChildProcess>>
class ChildProcessStub: public mojo::MessageReceiverWithResponderStatus {public:
........void set_sink(ImplPointerType sink) { sink_ = std::move(sink); }ImplPointerType& sink() { return sink_; }bool Accept(mojo::Message* message) override {if (ImplRefTraits::IsNull(sink_))return false;return ChildProcessStubDispatch::Accept(ImplRefTraits::GetRawPointer(&sink_), message);}bool AcceptWithResponder(mojo::Message* message,std::unique_ptr<mojo::MessageReceiverWithStatus> responder) override {if (ImplRefTraits::IsNull(sink_))return false;return ChildProcessStubDispatch::AcceptWithResponder(ImplRefTraits::GetRawPointer(&sink_), message, std::move(responder));}private:ImplPointerType sink_;
};

set_sink方法实际设置成员变量sink_, 实际指向ChildThreadImpl::IOThreadState实例。 当receiver收到消息后会调用Accept(异步)方法或者AcceptWithResponder(同步返回结果)方法。

Accept方法调用ChildProcessStubDispatch::Accept方法,第一个参数为sink_, 第二个参数为消息体。我们来看ChildProcessStubDispatch::Accept 方法
out/Default/gen/content/common/child_process.mojom.cc

1021 // static
1022 bool ChildProcessStubDispatch::Accept(
1023     ChildProcess* impl,
1024     mojo::Message* message) {
1025   switch (message->header()->name) {.......
1182     case internal::kChildProcess_BindServiceInterface_Name: {
1183 
1184       DCHECK(message->is_serialized());
1185       internal::ChildProcess_BindServiceInterface_Params_Data* params =
1186           reinterpret_cast<internal::ChildProcess_BindServiceInterface_Params_Data*>(
1187               message->mutable_payload());
1188 
1189       bool success = true;
1190       ::mojo::GenericPendingReceiver p_receiver{};
1191       ChildProcess_BindServiceInterface_ParamsDataView input_data_view(params, message);
1192 
1193       if (success && !input_data_view.ReadReceiver(&p_receiver))
1194         success = false;
1195       if (!success) {
1196         ReportValidationErrorForMessage(
1197             message,
1198             mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
1199             ChildProcess::Name_, 6, false);
1200         return false;
1201       }
1202       // A null |impl| means no implementation was bound.
1203       DCHECK(impl);
1204       impl->BindServiceInterface(
1205 std::move(p_receiver));
1206       return true;
1207     }
1208     case internal::kChildProcess_BindReceiver_Name: {
1209 
1210       DCHECK(message->is_serialized());
1211       internal::ChildProcess_BindReceiver_Params_Data* params =
1212           reinterpret_cast<internal::ChildProcess_BindReceiver_Params_Data*>(
1213               message->mutable_payload());
1214 
1215       bool success = true;
1216       ::mojo::GenericPendingReceiver p_receiver{};
1217       ChildProcess_BindReceiver_ParamsDataView input_data_view(params, message);
1218 
1219       if (success && !input_data_view.ReadReceiver(&p_receiver))
1220         success = false;
1221       if (!success) {
1222         ReportValidationErrorForMessage(
1223             message,
1224             mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
1225             ChildProcess::Name_, 7, false);
1226         return false;
1227       }
1228       // A null |impl| means no implementation was bound.
1229       DCHECK(impl);
1230       impl->BindReceiver(
1231 std::move(p_receiver));
1232       return true;
1233     }.......
1259     }
1260   }
1261   return false;
1262 }

函数很简单,根据message的名称反序列化参数,然后调用ChildThreadImpl::IOThreadState的对应方法。

以上就是典型的ipcz binding 使用。 整体通信借助ipcz 通道。

http://www.dinnco.com/news/43628.html

相关文章:

  • 快盘做网站服务器百度投诉电话
  • dedecms网站关键词百度竞价推广账户
  • 学做网站培训优化师助理
  • 360做网站和推广怎么样谷歌外贸网站推广
  • 专业企业网站建设公司网站收录入口
  • 如何建设个人独立网站新闻发稿平台有哪些
  • 长春网站制作公司百度网址大全 官网
  • 如何做微信网站做广告山东疫情最新情况
  • csgo翻硬币网站怎么做如何免费注册网站平台
  • 做电影资源网站服务器怎么选企业管理咨询培训
  • wordpress hpkp郑州seo学校
  • 用凡科做网站好弄吗佛山网络推广哪里好
  • 常见的营销策略有哪些百度关键词快速优化
  • 南阳百度网站推广网站服务费一年多少钱
  • 四川省建筑施工企业安管人员考试百度起诉seo公司
  • php做商城网站最新国际军事动态
  • 湛江网站建设咨询2022网站seo
  • 个人网站费用免费检测网站seo
  • 南通专业网站排名推广如何制作网站最简单的方法
  • 政府网站建设情况调查表企业网站优化服务
  • 做微信网站支付需要什么信息表河南网站关键词优化
  • 网站业务怎么做推广方案策划
  • 网站域名空间怎么提交免费域名注册永久
  • 怎么用html5做自适应网站免费收录网站提交
  • 苹果电脑做网站的步骤牛排seo
  • html个人网页代码优化设计单元测试卷答案
  • 成都疫情最新新闻百度seo可能消失
  • 外贸网站优化方案自己如何制作一个网站
  • vps 同时翻墙和做网站推广营销
  • 如何将自己做的网站传到网上seo优化论坛