1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2006, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/task.h" 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/taskrunner.h" 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base { 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint32 Task::unique_id_seed_ = 0; 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochTask::Task(TaskParent *parent) 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : TaskParent(this, parent), 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch state_(STATE_INIT), 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_(false), 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch done_(false), 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch aborted_(false), 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch busy_(false), 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_(false), 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch start_time_(0), 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_time_(0), 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_seconds_(0), 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_suspended_(false) { 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch unique_id_ = unique_id_seed_++; 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // sanity check that we didn't roll-over our id seed 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(unique_id_ < unique_id_seed_); 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochTask::~Task() { 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Is this task being deleted in the correct manner? 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(!done_ || GetRunner()->is_ok_to_delete(this)); 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(state_ == STATE_INIT || done_); 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(state_ == STATE_INIT || blocked_); 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If the task is being deleted without being done, it 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // means that it hasn't been removed from its parent. 62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // This happens if a task is deleted outside of TaskRunner. 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!done_) { 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Stop(); 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint64 Task::CurrentTime() { 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GetRunner()->CurrentTime(); 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint64 Task::ElapsedTime() { 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return CurrentTime() - start_time_; 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Start() { 77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (state_ != STATE_INIT) 78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Set the start time before starting the task. Otherwise if the task 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // finishes quickly and deletes the Task object, setting start_time_ 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // will crash. 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch start_time_ = CurrentTime(); 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetRunner()->StartTask(this); 84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Step() { 87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (done_) { 88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef _DEBUG 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we do not know how !blocked_ happens when done_ - should be impossible. 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // But it causes problems, so in retail build, we force blocked_, and 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // under debug we assert. 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(blocked_); 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = true; 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Async Error() was called 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (error_) { 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch done_ = true; 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch state_ = STATE_ERROR; 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = true; 104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// obsolete - an errored task is not considered done now 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// SignalDone(); 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Stop(); 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef _DEBUG 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // verify that stop removed this from its parent 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(!parent()->IsChildTask(this)); 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch busy_ = true; 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int new_state = Process(state_); 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch busy_ = false; 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (aborted_) { 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Abort(true); // no need to wake because we're awake 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (new_state == STATE_BLOCKED) { 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = true; 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Let the timeout continue 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch state_ = new_state; 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = false; 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ResetTimeout(); 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (new_state == STATE_DONE) { 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch done_ = true; 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (new_state == STATE_ERROR) { 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch done_ = true; 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_ = true; 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (done_) { 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// obsolete - call this yourself 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// SignalDone(); 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Stop(); 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if _DEBUG 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // verify that stop removed this from its parent 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(!parent()->IsChildTask(this)); 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = true; 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Abort(bool nowake) { 154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Why only check for done_ (instead of "aborted_ || done_")? 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If aborted_ && !done_, it means the logic for aborting still 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // needs to be executed (because busy_ must have been true when 158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Abort() was previously called). 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (done_) 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch aborted_ = true; 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!busy_) { 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch done_ = true; 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = true; 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_ = true; 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // "done_" is set before calling "Stop()" to ensure that this code 168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // doesn't execute more than once (recursively) for the same task. 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Stop(); 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef _DEBUG 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // verify that stop removed this from its parent 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(!parent()->IsChildTask(this)); 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!nowake) { 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // WakeTasks to self-delete. 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Don't call Wake() because it is a no-op after "done_" is set. 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Even if Wake() did run, it clears "blocked_" which isn't desireable. 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetRunner()->WakeTasks(); 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Wake() { 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (done_) 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (blocked_) { 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch blocked_ = false; 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetRunner()->WakeTasks(); 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Error() { 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (error_ || done_) 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_ = true; 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Wake(); 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string Task::GetStateName(int state) const { 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_BLOCKED("BLOCKED"); 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_INIT("INIT"); 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_START("START"); 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_DONE("DONE"); 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_ERROR("ERROR"); 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_RESPONSE("RESPONSE"); 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static const std::string STR_HUH("??"); 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (state) { 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_BLOCKED: return STR_BLOCKED; 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_INIT: return STR_INIT; 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_START: return STR_START; 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_DONE: return STR_DONE; 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_ERROR: return STR_ERROR; 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_RESPONSE: return STR_RESPONSE; 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_HUH; 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint Task::Process(int state) { 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int newstate = STATE_ERROR; 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (TimedOut()) { 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ClearTimeout(); 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch newstate = OnTimeout(); 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalTimeout(); 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (state) { 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_INIT: 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch newstate = STATE_START; 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_START: 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch newstate = ProcessStart(); 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_RESPONSE: 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch newstate = ProcessResponse(); 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_DONE: 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STATE_ERROR: 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch newstate = STATE_BLOCKED; 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return newstate; 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::Stop() { 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // No need to wake because we're either awake or in abort 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch TaskParent::OnStopped(this); 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::set_timeout_seconds(const int timeout_seconds) { 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_seconds_ = timeout_seconds; 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ResetTimeout(); 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool Task::TimedOut() { 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return timeout_seconds_ && 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_time_ && 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CurrentTime() >= timeout_time_; 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::ResetTimeout() { 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int64 previous_timeout_time = timeout_time_; 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool timeout_allowed = (state_ != STATE_INIT) 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch && (state_ != STATE_DONE) 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch && (state_ != STATE_ERROR); 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (timeout_seconds_ && timeout_allowed && !timeout_suspended_) 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_time_ = CurrentTime() + 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (timeout_seconds_ * kSecToMsec * kMsecTo100ns); 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_time_ = 0; 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::ClearTimeout() { 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int64 previous_timeout_time = timeout_time_; 278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_time_ = 0; 279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::SuspendTimeout() { 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!timeout_suspended_) { 284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_suspended_ = true; 285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ResetTimeout(); 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid Task::ResumeTimeout() { 290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (timeout_suspended_) { 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_suspended_ = false; 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ResetTimeout(); 293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace talk_base 297