15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/serial_worker.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerialWorker::SerialWorker() 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : message_loop_(base::MessageLoopProxy::current()), 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(IDLE) {} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerialWorker::~SerialWorker() {} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerialWorker::WorkNow() { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case IDLE: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::WorkerPool::PostTask(FROM_HERE, base::Bind( 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SerialWorker::DoWorkJob, this), false)) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See worker_pool_posix.cc. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "WorkerPool::PostTask is not expected to fail on posix"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to WorkerPool::PostTask, will retry later"; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const int kWorkerPoolRetryDelayMs = 100; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->PostDelayedTask( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SerialWorker::RetryWork, this), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kWorkerPoolRetryDelayMs)); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = WAITING; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = WORKING; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WORKING: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remember to re-read after |DoRead| finishes. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = PENDING; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CANCELLED: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PENDING: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected state " << state_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerialWorker::Cancel() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = CANCELLED; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerialWorker::DoWorkJob() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->DoWork(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this fails, the loop is gone, so there is no point retrying. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->PostTask(FROM_HERE, base::Bind( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SerialWorker::OnWorkJobFinished, this)); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerialWorker::OnWorkJobFinished() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CANCELLED: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WORKING: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = IDLE; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->OnWorkFinished(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PENDING: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = IDLE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkNow(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected state " << state_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerialWorker::RetryWork() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CANCELLED: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = IDLE; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkNow(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected state " << state_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101