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