日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

谷歌chrome浏览器的源码分析(六)

發(fā)布時間:2025/3/21 HTML 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 谷歌chrome浏览器的源码分析(六) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

消息的流通過程,是一個不同類相互交流的過程,如果不了解這個過程,根本就不知道這些類是怎么樣相互協(xié)作的。由于上一次說到ViewHostMsg_RequestResource消息已經(jīng)發(fā)送出來,它的處理過徎其實就是一般資源的消息處理過程,下面就來看看這個消息的處理過程,如下:

1.???????base::MessagePumpWin::Run函數(shù)消息

2.???????base::MessagePumpWin::RunWithDispatcher

3.???????base::MessagePumpWin::DoRunLoop

4.???????base::MessagePumpWin::WaitForWork

5.???????base::MessagePumpWin::SignalWatcher

6.???????IPC::Channel::OnObjectSignaled?通道的消息處理。

7.???????IPC::Channel::ProcessIncomingMessages

8.???????IPC::SyncChannel::SyncContext::OnMessageReceived

9.???????IPC::ChannelProxy::Context::TryFilters

10.????ResourceMessageFilter::OnMessageReceived

11.????IPC::MessageWithTuple<Tuple2<int,ViewHostMsg_Resource_Request> >::Dispatch<ResourceMessageFilter,int,ViewHostMsg_Resource_Request const &>

12.????ResourceMessageFilter::OnRequestResource

13.????ResourceDispatcherHost::BeginRequest

?

消息通過上面12個函數(shù)的流轉(zhuǎn),到達到處理這個消息的函數(shù)ResourceDispatcherHost::BeginRequest,它在里面就會把消息變成一個網(wǎng)絡(luò)下載請求,函數(shù)代碼如下:

#001??void ResourceDispatcherHost::BeginRequest(

#002??????Receiver* receiver,

#003??????HANDLE render_process_handle,

#004??????int render_process_host_id,

#005??????int render_view_id,

#006??????int request_id,

#007??????const ViewHostMsg_Resource_Request& request_data,

#008??????URLRequestContext* request_context,

#009??????IPC::Message* sync_result) {

?

是否已經(jīng)傳送完成,或者關(guān)閉。

#010????if (is_shutdown_ ||

#011????????!ShouldServiceRequest(render_process_host_id, request_data)) {

#012??????// Tell the renderer that this request was disallowed.

#013??????receiver->Send(new ViewMsg_Resource_RequestComplete(

#014??????????render_view_id,

#015??????????request_id,

#016??????????URLRequestStatus(URLRequestStatus::FAILED, net::ERR_ABORTED)));

#017??????return;

#018????}

#019?

?

保證所有插件已經(jīng)加載。

#020????// Ensure the Chrome plugins are loaded, as they may intercept network

#021????// requests.??Does nothing if they are already loaded.

#022????// TODO(mpcomplete): This takes 200 ms!??Investigate parallelizing this by

#023????// starting the load earlier in a BG thread.

#024????plugin_service_->LoadChromePlugins(this);

#025?

?

構(gòu)造事件處理器。

#026????// Construct the event handler.

#027????scoped_refptr<EventHandler> handler;

#028????if (sync_result) {

#029??????handler = new SyncEventHandler(receiver, request_data.url, sync_result);

#030????} else {

#031??????handler = new AsyncEventHandler(receiver,

#032?????????????????????????????????????render_process_host_id,

#033?????????????????????????????????????render_view_id,

#034?????????????????????????????????????render_process_handle,

#035?????????????????????????????????????request_data.url,

#036?????????????????????????????????????this);

#037????}

#038?

#039????if (HandleExternalProtocol(request_id, render_process_host_id, render_view_id,

#040???????????????????????????????request_data.url, request_data.resource_type,

#041???????????????????????????????handler)) {

#042??????return;

#043????}

#044?

?

構(gòu)造下載請求。

#045????// Construct the request.

#046????URLRequest* request = new URLRequest(request_data.url, this);

#047????request->set_method(request_data.method);

#048????request->set_policy_url(request_data.policy_url);

#049????request->set_referrer(request_data.referrer.spec());

#050????request->SetExtraRequestHeaders(request_data.headers);

#051????request->set_load_flags(request_data.load_flags);

#052????request->set_context(request_context);

#053????request->set_origin_pid(request_data.origin_pid);

#054?

?

設(shè)置上傳數(shù)據(jù)。

#055????// Set upload data.

#056????uint64 upload_size = 0;

#057????if (!request_data.upload_content.empty()) {

#058??????scoped_refptr<net::UploadData> upload = new net::UploadData();

#059??????upload->set_elements(request_data.upload_content);??// Deep copy.

#060??????request->set_upload(upload);

#061??????upload_size = upload->GetContentLength();

#062????}

#063?

?

安裝一個CrossSiteEventHandler事件處理器。

#064????// Install a CrossSiteEventHandler if this request is coming from a

#065????// RenderViewHost with a pending cross-site request.??We only check this for

#066????// MAIN_FRAME requests.

#067????// TODO(mpcomplete): remove "render_process_host_id != -1"

#068????//???????????????????when http://b/viewIssue?id=1080959 is fixed.

#069????if (request_data.resource_type == ResourceType::MAIN_FRAME &&

#070????????render_process_host_id != -1 &&

#071????????Singleton<CrossSiteRequestManager>::get()->

#072????????????HasPendingCrossSiteRequest(render_process_host_id, render_view_id)) {

#073??????// Wrap the event handler to be sure the current page's onunload handler

#074??????// has a chance to run before we render the new page.

#075??????handler = new CrossSiteEventHandler(handler,

#076?????????????????????????????????????????render_process_host_id,

#077?????????????????????????????????????????render_view_id,

#078?????????????????????????????????????????this);

#079????}

#080?

#081????if (safe_browsing_->enabled() &&

#082????????safe_browsing_->CanCheckUrl(request_data.url)) {

#083??????handler = new SafeBrowsingEventHandler(handler,

#084????????????????????????????????????????????render_process_host_id,

#085????????????????????????????????????????????render_view_id,

#086????????????????????????????????????????????request_data.url,

#087????????????????????????????????????????????request_data.resource_type,

#088????????????????????????????????????????????safe_browsing_,

#089????????????????????????????????????????????this);

#090????}

#091?

?

創(chuàng)建一個緩沖區(qū)處理。

#092????// Insert a buffered event handler before the actual one.

#093????handler = new BufferedEventHandler(handler, this, request);

#094?

#095????// Make extra info and read footer (contains request ID).

#096????ExtraRequestInfo* extra_info =

#097????????new ExtraRequestInfo(handler,

#098?????????????????????????????request_id,

#099????????????????????????????render_process_host_id,

#100?????????????????????????????render_view_id,

#101????????????????????????????request_data.mixed_content,

#102????????????????????????????request_data.resource_type,

#103?????????????????????????????upload_size);

#104????extra_info->allow_download =

#105????????ResourceType::IsFrame(request_data.resource_type);

#106????request->set_user_data(extra_info);??// takes pointer ownership

#107?

?

開始調(diào)用內(nèi)部處理請求函數(shù)。

#108????BeginRequestInternal(request, request_data.mixed_content);

#109??}

?

通過上面的分析,已經(jīng)知道消息轉(zhuǎn)換為一個請求任務(wù)URLRequest,這個任務(wù)就需要交給后面的工作進程來處理了,它是通過函數(shù)BeginRequestInternal來把任務(wù)進一步發(fā)送出去。





上一次說到怎么樣開始把任務(wù)發(fā)送出去,也就是調(diào)用函數(shù)BeginRequestInternal來把URL請求發(fā)送,它的代碼如下:

#001??void ResourceDispatcherHost::BeginRequestInternal(URLRequest* request,

#002???????????????????????????????????????????????????bool mixed_content) {

?

獲取請求信息。

#003????ExtraRequestInfo* info = ExtraInfoForRequest(request);

?

生成全局ID,然后保存到正在下載請求隊列里。

#004????GlobalRequestID global_id(info->render_process_host_id, info->request_id);

#005????pending_requests_[global_id] = request;

#006????if (mixed_content) {

#007??????// We don't start the request in that case.??The SSLManager will potentially

#008??????// change the request (potentially to indicate its content should be

#009??????// filtered) and start it itself.

#010??????SSLManager::OnMixedContentRequest(this, request, ui_loop_);

#011??????return;

#012????}

?

這里開始處理請求。

#013????request->Start();

#014?

?

啟動上傳狀態(tài)更新定時器。

#015????// Make sure we have the load state monitor running

#016????if (!update_load_states_timer_.IsRunning()) {

#017??????update_load_states_timer_.Start(

#018??????????TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec),

#019??????????this, &ResourceDispatcherHost::UpdateLoadStates);

#020????}

#021??}

?

通過上面的函數(shù)可以看到主要調(diào)用URLRequest::Start()來處理下載的請求,它的代碼如下:

#001??void URLRequest::Start() {

#002????DCHECK(!is_pending_);

#003????DCHECK(!job_);

#004?

?

創(chuàng)建一個下載的工作任務(wù)。

#005????job_ = GetJobManager()->CreateJob(this);

#006????job_->SetExtraRequestHeaders(extra_request_headers_);

#007?

?

判斷是否有數(shù)據(jù)需要上傳。

#008????if (upload_.get())

#009??????job_->SetUpload(upload_.get());

#010?

?

設(shè)置請下開始下載的時間,以便后面檢查超時的狀態(tài)。

#011????is_pending_ = true;

#012????response_info_.request_time = Time::Now();

#013?

#014????// Don't allow errors to be sent from within Start().

#015????// TODO(brettw) this may cause NotifyDone to be sent synchronously,

#016????// we probably don't want this: they should be sent asynchronously so

#017????// the caller does not get reentered.

?

這里把工作任務(wù)啟動運行。

#018????job_->Start();

#019??}

?

由于這里是對URL的HTTP請求下載數(shù)據(jù),所以這里的job_是類URLRequestHttpJob的實例,也就是調(diào)用函數(shù)URLRequestHttpJob::Start(),在函數(shù)URLRequestHttpJob::Start()的處理過程序如下:

1.???????URLRequestHttpJob::StartTransaction()

2.???????net::HttpCache::Transaction::Start

3.???????net::HttpCache::Transaction::BeginNetworkRequest()

4.???????net::HttpTransactionWinHttp::Start

5.???????net::HttpTransactionWinHttp::DidResolveProxy()

6.???????net::HttpTransactionWinHttp::OpenRequest

7.???????net::HttpTransactionWinHttp::SendRequest()

8.???????net::WinHttpRequestThrottle::SubmitRequest

9.???????net::WinHttpRequestThrottle::SendRequest

通過上面9個函數(shù)的調(diào)用處理,然后就會通過Windows的HTTP API進行發(fā)送請求和下載數(shù)據(jù)。我們來分析一下最后的函數(shù)WinHttpRequestThrottle::SendRequest,看看怎么樣調(diào)用Windows HTTP API函數(shù)來獲取數(shù)據(jù)的,它的代碼如下:

#001??BOOL WinHttpRequestThrottle::SendRequest(HINTERNET request_handle,

#002??????????????????????????????????????????DWORD total_size,

#003??????????????????????????????????????????DWORD_PTR context,

#004??????????????????????????????????????????bool report_async_error) {

?

下面就是調(diào)用Windows的API函數(shù)WinHttpSendRequest來發(fā)送請求,當(dāng)然在調(diào)用這個函數(shù)之前,需要調(diào)用函數(shù)WinHttpOpenRequest先打開一個TCP連接。

#005????BOOL ok = WinHttpSendRequest(request_handle,

#006????????????????????????????????WINHTTP_NO_ADDITIONAL_HEADERS,

#007?????????????????????????????????0,

#008????????????????????????????????WINHTTP_NO_REQUEST_DATA,

#009?????????????????????????????????0,

#010?????????????????????????????????total_size,

#011?????????????????????????????????context);

#012????if (!ok && report_async_error) {

#013??????WINHTTP_ASYNC_RESULT async_result = { API_SEND_REQUEST, GetLastError() };

?

出錯處理,就調(diào)用外面的回調(diào)函數(shù)。

#014??????HttpTransactionWinHttp::StatusCallback(

#015??????????request_handle, context,

#016??????????WINHTTP_CALLBACK_STATUS_REQUEST_ERROR,

#017??????????&async_result, sizeof(async_result));

#018????}

#019????return ok;

#020??}

?

通過前面一系列的分析學(xué)會chrome瀏覽器怎么樣輸入URL地址,以及怎么樣進行URL自動完成,然后把URL發(fā)送到渲染進程去處理,最后渲染進程又把資源下載請求發(fā)送到資源下載進程里處理,最后資源下載進程通過Windows HTTP API函數(shù)進行TCP連接,以及HTTP數(shù)據(jù)的上傳和下載。瀏覽器向網(wǎng)站發(fā)送請求的過程已經(jīng)分析完成了,那么HTTP API收到網(wǎng)頁的數(shù)據(jù)后,又是怎么樣處理的呢?下一次再來分析這個問題。




上一次說到使用WinHTTP函數(shù)來創(chuàng)建HTTP連接,并且使用它來發(fā)送請求,那么數(shù)據(jù)接收回來,當(dāng)然也是從它那里接收的,因此下面來分析它的接收數(shù)據(jù)的幾個函數(shù),然后再來看看chrome里收到數(shù)據(jù)后發(fā)送到那里處理。

在WinHTTP里使用WinHttpOpen函數(shù)來創(chuàng)建HTTP連接,然后使用WinHttpConnect連接需要下載數(shù)據(jù)的網(wǎng)站,接著調(diào)函數(shù)WinHttpOpenRequest來創(chuàng)建一個請求,使用函數(shù)WinHttpSendRequest發(fā)送HTTP請求,如果有數(shù)據(jù)發(fā)送到服務(wù)器,就通過WinHttpWriteData函數(shù)來發(fā)送,最后調(diào)用函數(shù)WinHttpReceiveResponse來查詢狀態(tài)碼,WinHttpQueryDataAvailable函數(shù)查詢可以接收到的數(shù)據(jù)大小,調(diào)用函數(shù)WinHttpQueryHeaders來查詢傳送回來的html頭的大小,調(diào)用函數(shù)WinHttpReadData來接收到WEB服務(wù)器發(fā)送回來的數(shù)據(jù)。

?

chrome就是通過下面的函數(shù)來實現(xiàn)數(shù)據(jù)接收的,如下:

#001??void HttpTransactionWinHttp::HandleStatusCallback(DWORD status,

#002???????????????????????????????????????????????????DWORD_PTR result,

#003???????????????????????????????????????????????????DWORD error,

#004???????????????????????????????????????????????????DWORD secure_failure) {

#005????int rv = ERR_FAILED;

#006?

#007????switch (status) {

#008??????case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:

#009????????rv = DidReceiveError(error, secure_failure);

#010????????break;

#011??????case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:

#012????????PopulateSSLInfo(secure_failure);

#013????????rv = DidSendRequest();

#014????????break;

#015??????case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:

#016????????rv = DidWriteData(static_cast<DWORD>(result));

#017????????break;

?

接收到HTTP協(xié)議頭的數(shù)據(jù) 。

#018??????case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:

#019????????rv = DidReceiveHeaders();

#020????????break;

?

接收HTTP協(xié)議的數(shù)據(jù) 。

#021??????case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:

#022????????rv = DidReadData(static_cast<DWORD>(result));

#023????????break;

#024??????default:

#025????????NOTREACHED() << "unexpected status code";

#026????}

#027?

#028????if (rv == ERR_IO_PENDING) {

#029??????session_callback_->AddRef();??// balanced when callback runs.

#030????} else if (callback_) {

#031??????DoCallback(rv);

#032????}

#033??}

?

通過上面的分析知道數(shù)據(jù)怎么樣從WinHTTP接收到,并且發(fā)送到下一個階段處理。






上一次說到通過WinHTTP來接收網(wǎng)絡(luò)數(shù)據(jù),但沒有具體介紹怎么樣接收,現(xiàn)在就來分析這方面的代碼。首先是通過函數(shù)WinHttpQueryHeaders來查詢HTTP協(xié)議頭的大小,接著還是通過函數(shù)WinHttpQueryHeaders把數(shù)據(jù)接收到緩沖區(qū)里。下面這段代碼,就是做這樣的事情:

#001??int HttpTransactionWinHttp::DidReceiveHeaders() {

#002????session_callback_->set_load_state(LOAD_STATE_IDLE);

#003?

?

第一次調(diào)用函數(shù)WinHttpQueryHeaders查看接收到協(xié)議頭的大小。

#004????DWORD size = 0;

#005????if (!WinHttpQueryHeaders(request_handle_,

#006????????????????????????????WINHTTP_QUERY_RAW_HEADERS,

#007????????????????????????????WINHTTP_HEADER_NAME_BY_INDEX,

#008?????????????????????????????NULL,

#009?????????????????????????????&size,

#010????????????????????????????WINHTTP_NO_HEADER_INDEX)) {

#011??????DWORD error = GetLastError();

#012??????if (error != ERROR_INSUFFICIENT_BUFFER) {

#013????????DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();

#014????????return TranslateLastOSError();

#015??????}

#016??????// OK, size should tell us how much to allocate...

#017??????DCHECK(size > 0);

#018????}

#019?

?

第二次調(diào)用函數(shù)WinHttpQueryHeaders來接收協(xié)議頭的數(shù)據(jù)。

#020????std::wstring raw_headers;

#021?

#022????// 'size' is the number of bytes rather than the number of characters.

#023????DCHECK(size % 2 == 0);

#024????if (!WinHttpQueryHeaders(request_handle_,

#025????????????????????????????WINHTTP_QUERY_RAW_HEADERS,

#026????????????????????????????WINHTTP_HEADER_NAME_BY_INDEX,

#027????????????????????????????WriteInto(&raw_headers, size/2 + 1),

#028?????????????????????????????&size,

#029????????????????????????????WINHTTP_NO_HEADER_INDEX)) {

#030??????DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();

#031??????return TranslateLastOSError();

#032????}

#033?

?

設(shè)置回應(yīng)的一些狀態(tài)。

#034????response_.response_time = Time::Now();

#035?

#036????// From experimentation, it appears that WinHttp translates non-ASCII bytes

#037????// found in the response headers to UTF-16 assuming that they are encoded

#038????// using the default system charset.??We attempt to undo that here.

#039????response_.headers =

#040????????new HttpResponseHeaders(base::SysWideToNativeMB(raw_headers));

#041?

#042????// WinHTTP truncates a response longer than 2GB.??Perhaps it stores the

#043????// response's content length in a signed 32-bit integer.??We fail rather

#044????// than reading a truncated response.

#045????if (response_.headers->GetContentLength() > 0x80000000)

#046??????return ERR_FILE_TOO_BIG;

#047?

#048????response_.vary_data.Init(*request_, *response_.headers);

#049????PopulateAuthChallenge();

#050?

#051????// Unfortunately, WinHttp does not close the connection when a non-keepalive

#052????// response is _not_ followed by the server closing the connection.?So, we

#053????// attempt to hack around this bug.

#054????if (!response_.headers->IsKeepAlive())

#055??????content_length_remaining_ = response_.headers->GetContentLength();

#056?

#057????return OK;

#058??}

?

通過上面的函數(shù)處理,就可以收到HTTP協(xié)議頭的數(shù)據(jù),這樣就可以進一步處理了。那么接著下來就是收到HTTP協(xié)議里的數(shù)據(jù),這個主要通過下面的函數(shù)來接收到的,如下:

#001??BOOL HttpTransactionWinHttp::SessionCallback::ReadData(

#002??????HINTERNET request_handle) {

#003????DCHECK(bytes_available_ >= 0);

#004????char* buf = read_buf_;

#005????read_buf_ = NULL;

#006????int bytes_to_read = std::min(bytes_available_, read_buf_len_);

#007????read_buf_len_ = 0;

#008????if (!bytes_to_read)

#009??????bytes_to_read = 1;

#010?

#011????// Because of how WinHTTP fills memory when used asynchronously, Purify isn't

#012????// able to detect that it's been initialized, so it scans for 0xcd in the

#013????// buffer and reports UMRs (uninitialized memory reads) for those individual

#014????// bytes. We override that to avoid the false error reports.

#015????// See http://b/issue?id=1173916.

#016????base::MemoryDebug::MarkAsInitialized(buf, bytes_to_read);

#017????return?WinHttpReadData(request_handle, buf, bytes_to_read, NULL);

#018??}

上面通過判斷可以接收到多少字節(jié),然后通過函數(shù)WinHttpReadData把數(shù)據(jù)保存到緩沖區(qū)read_buf_里,在這個緩沖區(qū)里保存了所有網(wǎng)絡(luò)接收到的數(shù)據(jù),那么這些數(shù)據(jù)又將要流向何方呢?下一次再來分析這個問題。





上次說到函數(shù)WinHttpReadData接收數(shù)據(jù)到緩沖區(qū)里,那么這些數(shù)據(jù)又是怎么樣傳送給下一步處理的呢?帶著這個問題,我們來分析下面這段代碼,如下:

#001??void HttpTransactionWinHttp::HandleStatusCallback(DWORD status,

#002???????????????????????????????????????????????????DWORD_PTR result,

#003???????????????????????????????????????????????????DWORD error,

#004???????????????????????????????????????????????????DWORD secure_failure) {

#005????int rv = ERR_FAILED;

#006?

#007????switch (status) {

#008??????case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:

#009????????rv = DidReceiveError(error, secure_failure);

#010????????break;

......

#027?

#028????if (rv == ERR_IO_PENDING) {

#029??????session_callback_->AddRef();??// balanced when callback runs.

#030????} else if (callback_) {

#031??????DoCallback(rv);

#032????}

#033??}

?

通過上面的函數(shù)可以看到,當(dāng)數(shù)據(jù)接收完成后,就會調(diào)用DoCallback函數(shù)處理接收到的數(shù)據(jù)。DoCallback函數(shù)的代碼如下:

?

#001??void HttpTransactionWinHttp::DoCallback(int rv) {

#002????DCHECK(rv != ERR_IO_PENDING);

#003????DCHECK(callback_);

#004?

#005????// since Run may result in Read being called, clear callback_ up front.

#006????CompletionCallback* c = callback_;

#007????callback_ = NULL;

#008????c->Run(rv);

#009??}

?

看到這里又是一個回調(diào)函數(shù)c->Run的通知,它是調(diào)用開始創(chuàng)建這個連接時設(shè)置的回調(diào)對象。如果是HTTP請求,那么這個請求回調(diào)函數(shù)是對象URLRequestHttpJob里的函數(shù),也就是調(diào)用URLRequestHttpJob::OnReadCompleted函數(shù),這個函數(shù)是當(dāng)數(shù)據(jù)接收完成,或接收失敗,或者接收還沒有完成時都會調(diào)用。這個函數(shù)代碼如下:

#001??void URLRequestHttpJob::OnReadCompleted(int result) {

#002????read_in_progress_ = false;

#003?

?

這里是接收數(shù)據(jù)完成。

#004????if (result == 0) {

#005??????NotifyDone(URLRequestStatus());

#006????} else if (result < 0) {

?

這里是接收數(shù)據(jù)出錯劃。

#007??????NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));

#008????} else {

?

這里是接收數(shù)據(jù)還沒有完成。

#009??????// Clear the IO_PENDING status

#010??????SetStatus(URLRequestStatus());

#011????}

#012?

#013????NotifyReadComplete(result);

#014??}

?

當(dāng)上面讀取數(shù)據(jù)完成時,就開始把接收到數(shù)據(jù)通過類ResourceDispatcherHost來發(fā)送出去,而類ResourceDispatcherHost發(fā)送數(shù)據(jù)的方式比較特別,它不是通過消息把整塊數(shù)據(jù)用命名管道發(fā)送的,而是通過共享內(nèi)存的方式讓另一個進程來讀取數(shù)據(jù),這樣達到速度快的特點,可見可多米處理處理考慮的都是速度,它的代碼如下:

#001??bool OnReadCompleted(int request_id, int* bytes_read) {

#002??????if (!*bytes_read)

#003????????return true;

#004??????DCHECK(read_buffer_.get());

#005?

#006??????if (!rdh_->WillSendData(render_process_host_id_, request_id)) {

#007????????// We should not send this data now, we have too many pending requests.

#008????????return true;

#009??????}

#010?

?

這里創(chuàng)建共享內(nèi)存。

#011??????SharedMemoryHandle handle;

#012??????if (!read_buffer_->GiveToProcess(render_process_, &handle)) {

#013????????// We wrongfully incremented the pending data count. Fake an ACK message

#014????????// to fix this. We can't move this call above the WillSendData because

#015????????// it's killing our read_buffer_, and we don't want that when we pause

#016????????// the request.

#017????????rdh_->OnDataReceivedACK(render_process_host_id_, request_id);

#018????????return false;

#019??????}

#020?

?

把共享內(nèi)存通過管道消息發(fā)送給渲染進程。

#021??????receiver_->Send(new ViewMsg_Resource_DataReceived(

#022??????????routing_id_, request_id, handle, *bytes_read));

#023?

#024??????return true;

#025????}

#026?

?

共享內(nèi)存是使用Windows API函數(shù)CreateFileMapping來創(chuàng)建內(nèi)存共享文件實現(xiàn)的,具體實現(xiàn)方法請參考類SharedMemory的實現(xiàn)。這里既然把消息通過管道發(fā)送出去了,那么在另一個線程里肯定就處理的這個消息,下一次再來分析那部份代碼。




from:?http://blog.csdn.net/caimouse/article/details/3230179

總結(jié)

以上是生活随笔為你收集整理的谷歌chrome浏览器的源码分析(六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。