• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/serial_worker.h"
6 
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/threading/worker_pool.h"
11 
12 namespace net {
13 
SerialWorker()14 SerialWorker::SerialWorker()
15   : message_loop_(base::MessageLoopProxy::current()),
16     state_(IDLE) {}
17 
~SerialWorker()18 SerialWorker::~SerialWorker() {}
19 
WorkNow()20 void SerialWorker::WorkNow() {
21   DCHECK(message_loop_->BelongsToCurrentThread());
22   switch (state_) {
23     case IDLE:
24       if (!base::WorkerPool::PostTask(FROM_HERE, base::Bind(
25           &SerialWorker::DoWorkJob, this), false)) {
26 #if defined(OS_POSIX)
27         // See worker_pool_posix.cc.
28         NOTREACHED() << "WorkerPool::PostTask is not expected to fail on posix";
29 #else
30         LOG(WARNING) << "Failed to WorkerPool::PostTask, will retry later";
31         const int kWorkerPoolRetryDelayMs = 100;
32         message_loop_->PostDelayedTask(
33             FROM_HERE,
34             base::Bind(&SerialWorker::RetryWork, this),
35             base::TimeDelta::FromMilliseconds(kWorkerPoolRetryDelayMs));
36         state_ = WAITING;
37         return;
38 #endif
39       }
40       state_ = WORKING;
41       return;
42     case WORKING:
43       // Remember to re-read after |DoRead| finishes.
44       state_ = PENDING;
45       return;
46     case CANCELLED:
47     case PENDING:
48     case WAITING:
49       return;
50     default:
51       NOTREACHED() << "Unexpected state " << state_;
52   }
53 }
54 
Cancel()55 void SerialWorker::Cancel() {
56   DCHECK(message_loop_->BelongsToCurrentThread());
57   state_ = CANCELLED;
58 }
59 
DoWorkJob()60 void SerialWorker::DoWorkJob() {
61   this->DoWork();
62   // If this fails, the loop is gone, so there is no point retrying.
63   message_loop_->PostTask(FROM_HERE, base::Bind(
64       &SerialWorker::OnWorkJobFinished, this));
65 }
66 
OnWorkJobFinished()67 void SerialWorker::OnWorkJobFinished() {
68   DCHECK(message_loop_->BelongsToCurrentThread());
69   switch (state_) {
70     case CANCELLED:
71       return;
72     case WORKING:
73       state_ = IDLE;
74       this->OnWorkFinished();
75       return;
76     case PENDING:
77       state_ = IDLE;
78       WorkNow();
79       return;
80     default:
81       NOTREACHED() << "Unexpected state " << state_;
82   }
83 }
84 
RetryWork()85 void SerialWorker::RetryWork() {
86   DCHECK(message_loop_->BelongsToCurrentThread());
87   switch (state_) {
88     case CANCELLED:
89       return;
90     case WAITING:
91       state_ = IDLE;
92       WorkNow();
93       return;
94     default:
95       NOTREACHED() << "Unexpected state " << state_;
96   }
97 }
98 
99 }  // namespace net
100 
101