Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: content/browser/service_worker/service_worker_version.cc

Issue 1027113002: Service Worker: Add a timeout for inflight requests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: dont use std::queue::swap Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_version.h" 5 #include "content/browser/service_worker/service_worker_version.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 template <typename IDMAP, typename... Params> 85 template <typename IDMAP, typename... Params>
86 void RunIDMapCallbacks(IDMAP* callbacks, const Params&... params) { 86 void RunIDMapCallbacks(IDMAP* callbacks, const Params&... params) {
87 typename IDMAP::iterator iter(callbacks); 87 typename IDMAP::iterator iter(callbacks);
88 while (!iter.IsAtEnd()) { 88 while (!iter.IsAtEnd()) {
89 iter.GetCurrentValue()->Run(params...); 89 iter.GetCurrentValue()->Run(params...);
90 iter.Advance(); 90 iter.Advance();
91 } 91 }
92 callbacks->Clear(); 92 callbacks->Clear();
93 } 93 }
94 94
95 template <typename CallbackType, typename... Params>
96 bool RunIDMapCallback(IDMap<CallbackType, IDMapOwnPointer>* callbacks,
97 int request_id,
98 const Params&... params) {
99 CallbackType* callback = callbacks->Lookup(request_id);
100 if (!callback)
101 return false;
102
103 callback->Run(params...);
104 callbacks->Remove(request_id);
105 return true;
106 }
107
95 void RunStartWorkerCallback( 108 void RunStartWorkerCallback(
96 const StatusCallback& callback, 109 const StatusCallback& callback,
97 scoped_refptr<ServiceWorkerRegistration> protect, 110 scoped_refptr<ServiceWorkerRegistration> protect,
98 ServiceWorkerStatusCode status) { 111 ServiceWorkerStatusCode status) {
99 callback.Run(status); 112 callback.Run(status);
100 } 113 }
101 114
102 // A callback adapter to start a |task| after StartWorker. 115 // A callback adapter to start a |task| after StartWorker.
103 void RunTaskAfterStartWorker( 116 void RunTaskAfterStartWorker(
104 base::WeakPtr<ServiceWorkerVersion> version, 117 base::WeakPtr<ServiceWorkerVersion> version,
(...skipping 30 matching lines...) Expand all
135 // Transfering the message ports failed, so destroy the ports. 148 // Transfering the message ports failed, so destroy the ports.
136 for (const TransferredMessagePort& port : sent_message_ports) { 149 for (const TransferredMessagePort& port : sent_message_ports) {
137 MessagePortService::GetInstance()->ClosePort(port.id); 150 MessagePortService::GetInstance()->ClosePort(port.id);
138 } 151 }
139 callback.Run(status); 152 callback.Run(status);
140 } 153 }
141 154
142 void RunErrorCrossOriginConnectCallback( 155 void RunErrorCrossOriginConnectCallback(
143 const ServiceWorkerVersion::CrossOriginConnectCallback& callback, 156 const ServiceWorkerVersion::CrossOriginConnectCallback& callback,
144 ServiceWorkerStatusCode status) { 157 ServiceWorkerStatusCode status) {
145 callback.Run(status, false); 158 callback.Run(status, false /* accept_connection */);
146 } 159 }
147 160
148 using WindowOpenedCallback = base::Callback<void(int, int)>; 161 using WindowOpenedCallback = base::Callback<void(int, int)>;
149 162
150 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a 163 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a
151 // new Window's WebContents to be initialized, run the |callback| passed to its 164 // new Window's WebContents to be initialized, run the |callback| passed to its
152 // constructor then self destroy. 165 // constructor then self destroy.
153 // The callback will receive the process and frame ids. If something went wrong 166 // The callback will receive the process and frame ids. If something went wrong
154 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). 167 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE).
155 // The callback will be called in the IO thread. 168 // The callback will be called in the IO thread.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 clients.push_back(info); 310 clients.push_back(info);
298 } 311 }
299 312
300 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 313 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
301 base::Bind(callback, clients)); 314 base::Bind(callback, clients));
302 } 315 }
303 316
304 } // namespace 317 } // namespace
305 318
306 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; 319 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5;
320 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5;
307 321
308 ServiceWorkerVersion::ServiceWorkerVersion( 322 ServiceWorkerVersion::ServiceWorkerVersion(
309 ServiceWorkerRegistration* registration, 323 ServiceWorkerRegistration* registration,
310 const GURL& script_url, 324 const GURL& script_url,
311 int64 version_id, 325 int64 version_id,
312 base::WeakPtr<ServiceWorkerContextCore> context) 326 base::WeakPtr<ServiceWorkerContextCore> context)
313 : version_id_(version_id), 327 : version_id_(version_id),
314 registration_id_(kInvalidServiceWorkerVersionId), 328 registration_id_(kInvalidServiceWorkerVersionId),
315 script_url_(script_url), 329 script_url_(script_url),
316 status_(NEW), 330 status_(NEW),
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 base::Bind(&self::DispatchFetchEvent, 543 base::Bind(&self::DispatchFetchEvent,
530 weak_factory_.GetWeakPtr(), 544 weak_factory_.GetWeakPtr(),
531 request, 545 request,
532 prepare_callback, 546 prepare_callback,
533 fetch_callback))); 547 fetch_callback)));
534 return; 548 return;
535 } 549 }
536 550
537 prepare_callback.Run(); 551 prepare_callback.Run();
538 552
539 int request_id = fetch_callbacks_.Add(new FetchCallback(fetch_callback)); 553 int request_id = AddRequest(fetch_callback, &fetch_callbacks_, REQUEST_FETCH);
540 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 554 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
541 ServiceWorkerMsg_FetchEvent(request_id, request)); 555 ServiceWorkerMsg_FetchEvent(request_id, request));
542 if (status != SERVICE_WORKER_OK) { 556 if (status != SERVICE_WORKER_OK) {
543 fetch_callbacks_.Remove(request_id); 557 fetch_callbacks_.Remove(request_id);
544 RunSoon(base::Bind(&RunErrorFetchCallback, 558 RunSoon(base::Bind(&RunErrorFetchCallback,
545 fetch_callback, 559 fetch_callback,
546 SERVICE_WORKER_ERROR_FAILED)); 560 SERVICE_WORKER_ERROR_FAILED));
547 } 561 }
548 } 562 }
549 563
550 void ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback& callback) { 564 void ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback& callback) {
551 DCHECK_EQ(ACTIVATED, status()) << status(); 565 DCHECK_EQ(ACTIVATED, status()) << status();
552 566
553 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( 567 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
554 switches::kEnableServiceWorkerSync)) { 568 switches::kEnableServiceWorkerSync)) {
555 callback.Run(SERVICE_WORKER_ERROR_ABORT); 569 callback.Run(SERVICE_WORKER_ERROR_ABORT);
556 return; 570 return;
557 } 571 }
558 572
559 if (running_status() != RUNNING) { 573 if (running_status() != RUNNING) {
560 // Schedule calling this method after starting the worker. 574 // Schedule calling this method after starting the worker.
561 StartWorker(base::Bind(&RunTaskAfterStartWorker, 575 StartWorker(base::Bind(&RunTaskAfterStartWorker,
562 weak_factory_.GetWeakPtr(), callback, 576 weak_factory_.GetWeakPtr(), callback,
563 base::Bind(&self::DispatchSyncEvent, 577 base::Bind(&self::DispatchSyncEvent,
564 weak_factory_.GetWeakPtr(), 578 weak_factory_.GetWeakPtr(),
565 callback))); 579 callback)));
566 return; 580 return;
567 } 581 }
568 582
569 int request_id = sync_callbacks_.Add(new StatusCallback(callback)); 583 int request_id = AddRequest(callback, &sync_callbacks_, REQUEST_SYNC);
570 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 584 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
571 ServiceWorkerMsg_SyncEvent(request_id)); 585 ServiceWorkerMsg_SyncEvent(request_id));
572 if (status != SERVICE_WORKER_OK) { 586 if (status != SERVICE_WORKER_OK) {
573 sync_callbacks_.Remove(request_id); 587 sync_callbacks_.Remove(request_id);
574 RunSoon(base::Bind(callback, status)); 588 RunSoon(base::Bind(callback, status));
575 } 589 }
576 } 590 }
577 591
578 void ServiceWorkerVersion::DispatchNotificationClickEvent( 592 void ServiceWorkerVersion::DispatchNotificationClickEvent(
579 const StatusCallback& callback, 593 const StatusCallback& callback,
580 const std::string& notification_id, 594 const std::string& notification_id,
581 const PlatformNotificationData& notification_data) { 595 const PlatformNotificationData& notification_data) {
582 DCHECK_EQ(ACTIVATED, status()) << status(); 596 DCHECK_EQ(ACTIVATED, status()) << status();
583 if (running_status() != RUNNING) { 597 if (running_status() != RUNNING) {
584 // Schedule calling this method after starting the worker. 598 // Schedule calling this method after starting the worker.
585 StartWorker(base::Bind(&RunTaskAfterStartWorker, 599 StartWorker(base::Bind(&RunTaskAfterStartWorker,
586 weak_factory_.GetWeakPtr(), callback, 600 weak_factory_.GetWeakPtr(), callback,
587 base::Bind(&self::DispatchNotificationClickEvent, 601 base::Bind(&self::DispatchNotificationClickEvent,
588 weak_factory_.GetWeakPtr(), 602 weak_factory_.GetWeakPtr(),
589 callback, notification_id, 603 callback, notification_id,
590 notification_data))); 604 notification_data)));
591 return; 605 return;
592 } 606 }
593 607
594 int request_id = 608 int request_id = AddRequest(callback, &notification_click_callbacks_,
595 notification_click_callbacks_.Add(new StatusCallback(callback)); 609 REQUEST_NOTIFICATION_CLICK);
596 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 610 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
597 ServiceWorkerMsg_NotificationClickEvent(request_id, 611 ServiceWorkerMsg_NotificationClickEvent(request_id,
598 notification_id, 612 notification_id,
599 notification_data)); 613 notification_data));
600 if (status != SERVICE_WORKER_OK) { 614 if (status != SERVICE_WORKER_OK) {
601 notification_click_callbacks_.Remove(request_id); 615 notification_click_callbacks_.Remove(request_id);
602 RunSoon(base::Bind(callback, status)); 616 RunSoon(base::Bind(callback, status));
603 } 617 }
604 } 618 }
605 619
606 void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback, 620 void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback,
607 const std::string& data) { 621 const std::string& data) {
608 DCHECK_EQ(ACTIVATED, status()) << status(); 622 DCHECK_EQ(ACTIVATED, status()) << status();
609 if (running_status() != RUNNING) { 623 if (running_status() != RUNNING) {
610 // Schedule calling this method after starting the worker. 624 // Schedule calling this method after starting the worker.
611 StartWorker(base::Bind(&RunTaskAfterStartWorker, 625 StartWorker(base::Bind(&RunTaskAfterStartWorker,
612 weak_factory_.GetWeakPtr(), callback, 626 weak_factory_.GetWeakPtr(), callback,
613 base::Bind(&self::DispatchPushEvent, 627 base::Bind(&self::DispatchPushEvent,
614 weak_factory_.GetWeakPtr(), 628 weak_factory_.GetWeakPtr(),
615 callback, data))); 629 callback, data)));
616 return; 630 return;
617 } 631 }
618 632
619 int request_id = push_callbacks_.Add(new StatusCallback(callback)); 633 int request_id = AddRequest(callback, &push_callbacks_, REQUEST_PUSH);
620 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 634 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
621 ServiceWorkerMsg_PushEvent(request_id, data)); 635 ServiceWorkerMsg_PushEvent(request_id, data));
622 if (status != SERVICE_WORKER_OK) { 636 if (status != SERVICE_WORKER_OK) {
623 push_callbacks_.Remove(request_id); 637 push_callbacks_.Remove(request_id);
624 RunSoon(base::Bind(callback, status)); 638 RunSoon(base::Bind(callback, status));
625 } 639 }
626 } 640 }
627 641
628 void ServiceWorkerVersion::DispatchGeofencingEvent( 642 void ServiceWorkerVersion::DispatchGeofencingEvent(
629 const StatusCallback& callback, 643 const StatusCallback& callback,
(...skipping 15 matching lines...) Expand all
645 callback, 659 callback,
646 base::Bind(&self::DispatchGeofencingEvent, 660 base::Bind(&self::DispatchGeofencingEvent,
647 weak_factory_.GetWeakPtr(), 661 weak_factory_.GetWeakPtr(),
648 callback, 662 callback,
649 event_type, 663 event_type,
650 region_id, 664 region_id,
651 region))); 665 region)));
652 return; 666 return;
653 } 667 }
654 668
655 int request_id = geofencing_callbacks_.Add(new StatusCallback(callback)); 669 int request_id =
670 AddRequest(callback, &geofencing_callbacks_, REQUEST_GEOFENCING);
656 ServiceWorkerStatusCode status = 671 ServiceWorkerStatusCode status =
657 embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent( 672 embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent(
658 request_id, event_type, region_id, region)); 673 request_id, event_type, region_id, region));
659 if (status != SERVICE_WORKER_OK) { 674 if (status != SERVICE_WORKER_OK) {
660 geofencing_callbacks_.Remove(request_id); 675 geofencing_callbacks_.Remove(request_id);
661 RunSoon(base::Bind(callback, status)); 676 RunSoon(base::Bind(callback, status));
662 } 677 }
663 } 678 }
664 679
665 void ServiceWorkerVersion::DispatchCrossOriginConnectEvent( 680 void ServiceWorkerVersion::DispatchCrossOriginConnectEvent(
(...skipping 10 matching lines...) Expand all
676 if (running_status() != RUNNING) { 691 if (running_status() != RUNNING) {
677 // Schedule calling this method after starting the worker. 692 // Schedule calling this method after starting the worker.
678 StartWorker( 693 StartWorker(
679 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), 694 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
680 base::Bind(&RunErrorCrossOriginConnectCallback, callback), 695 base::Bind(&RunErrorCrossOriginConnectCallback, callback),
681 base::Bind(&self::DispatchCrossOriginConnectEvent, 696 base::Bind(&self::DispatchCrossOriginConnectEvent,
682 weak_factory_.GetWeakPtr(), callback, client))); 697 weak_factory_.GetWeakPtr(), callback, client)));
683 return; 698 return;
684 } 699 }
685 700
686 int request_id = cross_origin_connect_callbacks_.Add( 701 int request_id = AddRequest(callback, &cross_origin_connect_callbacks_,
687 new CrossOriginConnectCallback(callback)); 702 REQUEST_CROSS_ORIGIN_CONNECT);
688 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 703 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
689 ServiceWorkerMsg_CrossOriginConnectEvent(request_id, client)); 704 ServiceWorkerMsg_CrossOriginConnectEvent(request_id, client));
690 if (status != SERVICE_WORKER_OK) { 705 if (status != SERVICE_WORKER_OK) {
691 cross_origin_connect_callbacks_.Remove(request_id); 706 cross_origin_connect_callbacks_.Remove(request_id);
692 RunSoon(base::Bind(callback, status, false)); 707 RunSoon(base::Bind(callback, status, false));
693 } 708 }
694 } 709 }
695 710
696 void ServiceWorkerVersion::DispatchCrossOriginMessageEvent( 711 void ServiceWorkerVersion::DispatchCrossOriginMessageEvent(
697 const NavigatorConnectClient& client, 712 const NavigatorConnectClient& client,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 if (is_doomed_) 788 if (is_doomed_)
774 return; 789 return;
775 is_doomed_ = true; 790 is_doomed_ = true;
776 if (!HasControllee()) 791 if (!HasControllee())
777 DoomInternal(); 792 DoomInternal();
778 } 793 }
779 794
780 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { 795 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
781 embedded_worker()->set_devtools_attached(attached); 796 embedded_worker()->set_devtools_attached(attached);
782 if (attached) { 797 if (attached) {
798 // TODO(falken): Canceling the timeouts when debugging could cause
799 // heisenbugs; we should instead run them as normal show an educational
800 // message in DevTools when they occur. crbug.com/470419
801
783 // Don't record the startup time metric once DevTools is attached. 802 // Don't record the startup time metric once DevTools is attached.
784 ClearTick(&start_time_); 803 ClearTick(&start_time_);
785 skip_recording_startup_time_ = true; 804 skip_recording_startup_time_ = true;
805
806 // Cancel request timeouts.
807 SetAllRequestTimes(base::TimeTicks());
786 return; 808 return;
787 } 809 }
788 if (!start_callbacks_.empty()) { 810 if (!start_callbacks_.empty()) {
789 // Reactivate the timer for start timeout. 811 // Reactivate the timer for start timeout.
790 DCHECK(timeout_timer_.IsRunning()); 812 DCHECK(timeout_timer_.IsRunning());
791 DCHECK(running_status() == STARTING || running_status() == STOPPING) 813 DCHECK(running_status() == STARTING || running_status() == STOPPING)
792 << running_status(); 814 << running_status();
793 RestartTick(&start_time_); 815 RestartTick(&start_time_);
794 } 816 }
817
818 // Reactivate request timeouts.
819 SetAllRequestTimes(base::TimeTicks::Now());
795 } 820 }
796 821
797 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( 822 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
798 const net::HttpResponseInfo& http_info) { 823 const net::HttpResponseInfo& http_info) {
799 main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); 824 main_script_http_info_.reset(new net::HttpResponseInfo(http_info));
800 } 825 }
801 826
802 const net::HttpResponseInfo* 827 const net::HttpResponseInfo*
803 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { 828 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() {
804 return main_script_http_info_.get(); 829 return main_script_http_info_.get();
805 } 830 }
806 831
832 ServiceWorkerVersion::RequestInfo::RequestInfo(int id, RequestType type)
833 : id(id), type(type), time(base::TimeTicks::Now()) {
834 }
835
836 ServiceWorkerVersion::RequestInfo::~RequestInfo() {
837 }
838
807 void ServiceWorkerVersion::OnScriptLoaded() { 839 void ServiceWorkerVersion::OnScriptLoaded() {
808 DCHECK_EQ(STARTING, running_status()); 840 DCHECK_EQ(STARTING, running_status());
809 // Activate ping/pong now that JavaScript execution will start. 841 // Activate ping/pong now that JavaScript execution will start.
810 ping_state_ = PINGING; 842 ping_state_ = PINGING;
811 } 843 }
812 844
813 void ServiceWorkerVersion::OnStarting() { 845 void ServiceWorkerVersion::OnStarting() {
814 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); 846 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this));
815 } 847 }
816 848
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 ServiceWorkerStatusCode status) { 991 ServiceWorkerStatusCode status) {
960 if (status != SERVICE_WORKER_OK) 992 if (status != SERVICE_WORKER_OK)
961 RunCallbacks(this, &start_callbacks_, status); 993 RunCallbacks(this, &start_callbacks_, status);
962 } 994 }
963 995
964 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker( 996 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker(
965 const StatusCallback& callback) { 997 const StatusCallback& callback) {
966 DCHECK_EQ(RUNNING, running_status()) 998 DCHECK_EQ(RUNNING, running_status())
967 << "Worker stopped too soon after it was started."; 999 << "Worker stopped too soon after it was started.";
968 1000
969 int request_id = install_callbacks_.Add(new StatusCallback(callback)); 1001 int request_id = AddRequest(callback, &install_callbacks_, REQUEST_INSTALL);
970 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( 1002 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
971 ServiceWorkerMsg_InstallEvent(request_id)); 1003 ServiceWorkerMsg_InstallEvent(request_id));
972 if (status != SERVICE_WORKER_OK) { 1004 if (status != SERVICE_WORKER_OK) {
973 install_callbacks_.Remove(request_id); 1005 install_callbacks_.Remove(request_id);
974 RunSoon(base::Bind(callback, status)); 1006 RunSoon(base::Bind(callback, status));
975 } 1007 }
976 } 1008 }
977 1009
978 void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker( 1010 void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker(
979 const StatusCallback& callback) { 1011 const StatusCallback& callback) {
980 DCHECK_EQ(RUNNING, running_status()) 1012 DCHECK_EQ(RUNNING, running_status())
981 << "Worker stopped too soon after it was started."; 1013 << "Worker stopped too soon after it was started.";
982 1014
983 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); 1015 int request_id = AddRequest(callback, &activate_callbacks_, REQUEST_ACTIVATE);
984 ServiceWorkerStatusCode status = 1016 ServiceWorkerStatusCode status =
985 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); 1017 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id));
986 if (status != SERVICE_WORKER_OK) { 1018 if (status != SERVICE_WORKER_OK) {
987 activate_callbacks_.Remove(request_id); 1019 activate_callbacks_.Remove(request_id);
988 RunSoon(base::Bind(callback, status)); 1020 RunSoon(base::Bind(callback, status));
989 } 1021 }
990 } 1022 }
991 1023
992 void ServiceWorkerVersion::OnGetClients( 1024 void ServiceWorkerVersion::OnGetClients(
993 int request_id, 1025 int request_id,
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { 1566 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) {
1535 DCHECK(running_status() == STARTING || running_status() == STOPPING) 1567 DCHECK(running_status() == STARTING || running_status() == STOPPING)
1536 << running_status(); 1568 << running_status();
1537 scoped_refptr<ServiceWorkerVersion> protect(this); 1569 scoped_refptr<ServiceWorkerVersion> protect(this);
1538 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); 1570 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT);
1539 if (running_status() == STARTING) 1571 if (running_status() == STARTING)
1540 embedded_worker_->Stop(); 1572 embedded_worker_->Stop();
1541 return; 1573 return;
1542 } 1574 }
1543 1575
1544 // This check occurs after the start_time_ timeout check, since in that case 1576 // Requests have not finished within a certain period.
1545 // the start callbacks should fail with ERROR_TIMEOUT. In the other timeout 1577 bool request_timed_out = false;
1546 // checks, there's nothing more to do as the worker is already stopping. 1578 while (!requests_.empty()) {
1579 RequestInfo info = requests_.front();
1580 if (GetTickDuration(info.time) <
1581 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes))
1582 break;
1583 if (OnRequestTimeout(info))
1584 request_timed_out = true;
1585 requests_.pop();
1586 }
1587 if (request_timed_out && running_status() != STOPPING)
1588 embedded_worker_->Stop();
1589
1590 // For the timeouts below, there are no callbacks to timeout so there is
1591 // nothing more to do if the worker is already stopping.
1547 if (running_status() == STOPPING) 1592 if (running_status() == STOPPING)
1548 return; 1593 return;
1549 1594
1550 // The worker has been idle for longer than a certain period. 1595 // The worker has been idle for longer than a certain period.
1551 if (GetTickDuration(idle_time_) > 1596 if (GetTickDuration(idle_time_) >
1552 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) { 1597 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) {
1553 StopWorkerIfIdle(); 1598 StopWorkerIfIdle();
1554 return; 1599 return;
1555 } 1600 }
1556 1601
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 IDMAP* callbacks, 1719 IDMAP* callbacks,
1675 int request_id) { 1720 int request_id) {
1676 callbacks->Remove(request_id); 1721 callbacks->Remove(request_id);
1677 if (is_doomed_) { 1722 if (is_doomed_) {
1678 // The stop should be already scheduled, but try to stop immediately, in 1723 // The stop should be already scheduled, but try to stop immediately, in
1679 // order to release worker resources soon. 1724 // order to release worker resources soon.
1680 StopWorkerIfIdle(); 1725 StopWorkerIfIdle();
1681 } 1726 }
1682 } 1727 }
1683 1728
1729 template <typename CallbackType>
1730 int ServiceWorkerVersion::AddRequest(
1731 const CallbackType& callback,
1732 IDMap<CallbackType, IDMapOwnPointer>* callback_map,
1733 RequestType request_type) {
1734 int request_id = callback_map->Add(new CallbackType(callback));
1735 requests_.push(RequestInfo(request_id, request_type));
1736 return request_id;
1737 }
1738
1739 bool ServiceWorkerVersion::OnRequestTimeout(const RequestInfo& info) {
1740 switch (info.type) {
1741 case REQUEST_ACTIVATE:
1742 return RunIDMapCallback(&activate_callbacks_, info.id,
1743 SERVICE_WORKER_ERROR_TIMEOUT);
1744 case REQUEST_INSTALL:
1745 return RunIDMapCallback(&install_callbacks_, info.id,
1746 SERVICE_WORKER_ERROR_TIMEOUT);
1747 case REQUEST_FETCH:
1748 return RunIDMapCallback(
1749 &fetch_callbacks_, info.id, SERVICE_WORKER_ERROR_TIMEOUT,
1750 /* The other args are ignored for non-OK status. */
1751 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse());
1752 case REQUEST_SYNC:
1753 return RunIDMapCallback(&sync_callbacks_, info.id,
1754 SERVICE_WORKER_ERROR_TIMEOUT);
1755 case REQUEST_NOTIFICATION_CLICK:
1756 return RunIDMapCallback(&notification_click_callbacks_, info.id,
1757 SERVICE_WORKER_ERROR_TIMEOUT);
1758 case REQUEST_PUSH:
1759 return RunIDMapCallback(&push_callbacks_, info.id,
1760 SERVICE_WORKER_ERROR_TIMEOUT);
1761 case REQUEST_GEOFENCING:
1762 return RunIDMapCallback(&geofencing_callbacks_, info.id,
1763 SERVICE_WORKER_ERROR_TIMEOUT);
1764 case REQUEST_CROSS_ORIGIN_CONNECT:
1765 return RunIDMapCallback(&cross_origin_connect_callbacks_, info.id,
1766 SERVICE_WORKER_ERROR_TIMEOUT,
1767 false /* accept_connection */);
1768 }
1769 NOTREACHED() << "Got unexpected request type: " << info.type;
1770 return false;
1771 }
1772
1773 void ServiceWorkerVersion::SetAllRequestTimes(const base::TimeTicks& ticks) {
1774 std::queue<RequestInfo> new_requests;
1775 while (!requests_.empty()) {
1776 RequestInfo info = requests_.front();
1777 info.time = ticks;
1778 new_requests.push(info);
1779 requests_.pop();
1780 }
1781 requests_ = new_requests;
1782 }
1783
1684 } // namespace content 1784 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698