日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

谷歌瀏覽器的源碼分析(30)

系統 2374 0
?

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

#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 ? }

?

通過上面的函數可以看到,當數據接收完成后,就會調用 DoCallback 函數處理接收到的數據。 DoCallback 函數的代碼如下:

?

#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 ? }

?

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

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

#002 ??? read_in_progress_ = false;

#003 ?

?

這里是接收數據完成。

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

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

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

?

這里是接收數據出錯劃。

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

#008 ??? } else {

?

這里是接收數據還沒有完成。

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

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

#011 ??? }

#012 ?

#013 ??? NotifyReadComplete(result);

#014 ? }

?

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

#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 ?

?

這里創建共享內存。

#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 ?

?

把共享內存通過管道消息發送給渲染進程。

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

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

#023 ?

#024 ????? return true;

#025 ??? }

#026 ?

?

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

谷歌瀏覽器的源碼分析(30)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 曲麻莱县| 花莲市| 新龙县| 西吉县| 海阳市| 建水县| 门源| 怀柔区| 黄大仙区| 寿阳县| 米林县| 武威市| 理塘县| 天祝| 舞钢市| 宝应县| 同心县| 融水| 札达县| 兴城市| 天长市| 哈密市| 察雅县| 闸北区| 灵山县| 静海县| 江阴市| 黎川县| 西丰县| 巫溪县| 翁牛特旗| 报价| 武清区| 阜康市| 察雅县| 伊川县| 两当县| 获嘉县| 襄汾县| 莎车县| 疏勒县|