diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-05 17:15:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-11 07:47:18 +0000 |
commit | 7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch) | |
tree | a3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/third_party/libjingle_xmpp | |
parent | 6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff) | |
download | qtwebengine-chromium-7324afb043a0b1e623d8e8eb906cdc53bdeb4685.tar.gz |
BASELINE: Update Chromium to 58.0.3029.54
Change-Id: I67f57065a7afdc8e4614adb5c0230281428df4d1
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/third_party/libjingle_xmpp')
31 files changed, 1514 insertions, 61 deletions
diff --git a/chromium/third_party/libjingle_xmpp/BUILD.gn b/chromium/third_party/libjingle_xmpp/BUILD.gn index 6b01b4fa0c4..b9435f28395 100644 --- a/chromium/third_party/libjingle_xmpp/BUILD.gn +++ b/chromium/third_party/libjingle_xmpp/BUILD.gn @@ -3,7 +3,7 @@ # found in the LICENSE file. # TODO(kjellander): Remove remaining dependencies on the WebRTC codebase. -import("../webrtc/build/webrtc.gni") +import("../webrtc/webrtc.gni") group("libjingle_xmpp") { public_deps = [ @@ -12,6 +12,17 @@ group("libjingle_xmpp") { ] } +rtc_static_library("rtc_task_runner") { + sources = [ + "task_runner/task.cc", + "task_runner/task.h", + "task_runner/taskparent.cc", + "task_runner/taskparent.h", + "task_runner/taskrunner.cc", + "task_runner/taskrunner.h", + ] +} + rtc_static_library("rtc_xmllite") { sources = [ "xmllite/qname.cc", @@ -47,13 +58,6 @@ config("rtc_xmpp_warnings_config") { } } -config("rtc_xmpp_inherited_config") { - defines = [ - "FEATURE_ENABLE_SSL", - "FEATURE_ENABLE_VOICEMAIL", - ] -} - rtc_static_library("rtc_xmpp") { cflags = [] sources = [ @@ -84,19 +88,18 @@ rtc_static_library("rtc_xmpp") { "xmpp/xmpptask.h", ] - defines = [ "FEATURE_ENABLE_SSL" ] + defines = [] deps = [ ":rtc_xmllite", "//third_party/webrtc/base:rtc_base", ] public_deps = [ + ":rtc_task_runner", "//third_party/expat", ] configs += [ ":rtc_xmpp_warnings_config" ] - public_configs = [ ":rtc_xmpp_inherited_config" ] - if (is_nacl) { deps += [ "//native_client_sdk/src/libraries/nacl_io" ] } @@ -127,6 +130,7 @@ rtc_test("libjingle_xmpp_unittests") { deps = [ ":libjingle_xmpp", + ":rtc_task_runner", # TODO(kjellander): Refactor/remove this dependency. It is needed by # third_party/webrtc_overrides/webrtc/base/win32socketinit.cc. @@ -136,6 +140,7 @@ rtc_test("libjingle_xmpp_unittests") { sources = [ "run_all_unittests.cc", + "task_runner/task_unittest.cc", "xmllite/qname_unittest.cc", "xmllite/xmlbuilder_unittest.cc", "xmllite/xmlelement_unittest.cc", diff --git a/chromium/third_party/libjingle_xmpp/OWNERS b/chromium/third_party/libjingle_xmpp/OWNERS index e5606c61ae9..9bb4b7e8a81 100644 --- a/chromium/third_party/libjingle_xmpp/OWNERS +++ b/chromium/third_party/libjingle_xmpp/OWNERS @@ -1,6 +1,5 @@ henrika@chromium.org henrikg@chromium.org hta@chromium.org -perkj@chromium.org sergeyu@chromium.org tommi@chromium.org diff --git a/chromium/third_party/libjingle_xmpp/README.chromium b/chromium/third_party/libjingle_xmpp/README.chromium index 2fa85aaf510..a3ece4c9cf2 100644 --- a/chromium/third_party/libjingle_xmpp/README.chromium +++ b/chromium/third_party/libjingle_xmpp/README.chromium @@ -11,10 +11,14 @@ XMPP (Extensible Messaging and Presence Protocol) is a communications protocol for messaging based on XML. xmllite is a minimalistic library for parsing and generating XML. The source for these libraries originates from the libjingle project, which was merged into the WebRTC codebase where it received minor -updates. As time passed, the code was no longer used in WebRTC but is still used -in Chromium. Only the parts that are used in Chromium are added here. +updates. The code in the task_runner subdirectory used to live in +third_party/webrtc/base, and it is a dependency for these libraries and +Chromium's jingle component. As time passed, the code was no longer used in +WebRTC but is still used in Chromium. Only the parts that are used in Chromium +are added here. Local Modifications: -* Include paths in third_party/libjingle_xmpp/xmllite and - third_party/libjingle_xmpp/xmpp are updated to reflect the new - absolute paths to their own headers. +* Include paths in third_party/libjingle_xmpp/xmllite, + third_party/libjingle_xmpp/xmpp, and third_party/libjingle_xmpp/task_runner + are updated to reflect the new absolute paths to their own and webrtc's + headers. diff --git a/chromium/third_party/libjingle_xmpp/task_runner/DEPS b/chromium/third_party/libjingle_xmpp/task_runner/DEPS new file mode 100644 index 00000000000..9f9d7f27873 --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+third_party/webrtc/base", +] diff --git a/chromium/third_party/libjingle_xmpp/task_runner/task.cc b/chromium/third_party/libjingle_xmpp/task_runner/task.cc new file mode 100644 index 00000000000..27eb02955a3 --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/task.cc @@ -0,0 +1,283 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/task_runner/task.h" +#include "third_party/libjingle_xmpp/task_runner/taskrunner.h" +#include "third_party/webrtc/base/checks.h" + +namespace rtc { + +int32_t Task::unique_id_seed_ = 0; + +Task::Task(TaskParent *parent) + : TaskParent(this, parent), + state_(STATE_INIT), + blocked_(false), + done_(false), + aborted_(false), + busy_(false), + error_(false), + start_time_(0), + timeout_time_(0), + timeout_seconds_(0), + timeout_suspended_(false) { + unique_id_ = unique_id_seed_++; + + // sanity check that we didn't roll-over our id seed + RTC_DCHECK(unique_id_ < unique_id_seed_); +} + +Task::~Task() { + // Is this task being deleted in the correct manner? +#if RTC_DCHECK_IS_ON + RTC_DCHECK(!done_ || GetRunner()->is_ok_to_delete(this)); +#endif + RTC_DCHECK(state_ == STATE_INIT || done_); + RTC_DCHECK(state_ == STATE_INIT || blocked_); + + // If the task is being deleted without being done, it + // means that it hasn't been removed from its parent. + // This happens if a task is deleted outside of TaskRunner. + if (!done_) { + Stop(); + } +} + +int64_t Task::CurrentTime() { + return GetRunner()->CurrentTime(); +} + +int64_t Task::ElapsedTime() { + return CurrentTime() - start_time_; +} + +void Task::Start() { + if (state_ != STATE_INIT) + return; + // Set the start time before starting the task. Otherwise if the task + // finishes quickly and deletes the Task object, setting start_time_ + // will crash. + start_time_ = CurrentTime(); + GetRunner()->StartTask(this); +} + +void Task::Step() { + if (done_) { +#if RTC_DCHECK_IS_ON + // we do not know how !blocked_ happens when done_ - should be impossible. + // But it causes problems, so in retail build, we force blocked_, and + // under debug we assert. + RTC_DCHECK(blocked_); +#else + blocked_ = true; +#endif + return; + } + + // Async Error() was called + if (error_) { + done_ = true; + state_ = STATE_ERROR; + blocked_ = true; +// obsolete - an errored task is not considered done now +// SignalDone(); + + Stop(); +#if RTC_DCHECK_IS_ON + // verify that stop removed this from its parent + RTC_DCHECK(!parent()->IsChildTask(this)); +#endif + return; + } + + busy_ = true; + int new_state = Process(state_); + busy_ = false; + + if (aborted_) { + Abort(true); // no need to wake because we're awake + return; + } + + if (new_state == STATE_BLOCKED) { + blocked_ = true; + // Let the timeout continue + } else { + state_ = new_state; + blocked_ = false; + ResetTimeout(); + } + + if (new_state == STATE_DONE) { + done_ = true; + } else if (new_state == STATE_ERROR) { + done_ = true; + error_ = true; + } + + if (done_) { +// obsolete - call this yourself +// SignalDone(); + + Stop(); +#if RTC_DCHECK_IS_ON + // verify that stop removed this from its parent + RTC_DCHECK(!parent()->IsChildTask(this)); +#endif + blocked_ = true; + } +} + +void Task::Abort(bool nowake) { + // Why only check for done_ (instead of "aborted_ || done_")? + // + // If aborted_ && !done_, it means the logic for aborting still + // needs to be executed (because busy_ must have been true when + // Abort() was previously called). + if (done_) + return; + aborted_ = true; + if (!busy_) { + done_ = true; + blocked_ = true; + error_ = true; + + // "done_" is set before calling "Stop()" to ensure that this code + // doesn't execute more than once (recursively) for the same task. + Stop(); +#if RTC_DCHECK_IS_ON + // verify that stop removed this from its parent + RTC_DCHECK(!parent()->IsChildTask(this)); +#endif + if (!nowake) { + // WakeTasks to self-delete. + // Don't call Wake() because it is a no-op after "done_" is set. + // Even if Wake() did run, it clears "blocked_" which isn't desireable. + GetRunner()->WakeTasks(); + } + } +} + +void Task::Wake() { + if (done_) + return; + if (blocked_) { + blocked_ = false; + GetRunner()->WakeTasks(); + } +} + +void Task::Error() { + if (error_ || done_) + return; + error_ = true; + Wake(); +} + +std::string Task::GetStateName(int state) const { + switch (state) { + case STATE_BLOCKED: return "BLOCKED"; + case STATE_INIT: return "INIT"; + case STATE_START: return "START"; + case STATE_DONE: return "DONE"; + case STATE_ERROR: return "ERROR"; + case STATE_RESPONSE: return "RESPONSE"; + } + return "??"; +} + +int Task::Process(int state) { + int newstate = STATE_ERROR; + + if (TimedOut()) { + ClearTimeout(); + newstate = OnTimeout(); + SignalTimeout(); + } else { + switch (state) { + case STATE_INIT: + newstate = STATE_START; + break; + case STATE_START: + newstate = ProcessStart(); + break; + case STATE_RESPONSE: + newstate = ProcessResponse(); + break; + case STATE_DONE: + case STATE_ERROR: + newstate = STATE_BLOCKED; + break; + } + } + + return newstate; +} + +void Task::Stop() { + // No need to wake because we're either awake or in abort + TaskParent::OnStopped(this); +} + +int Task::ProcessResponse() { + return STATE_DONE; +} + +void Task::set_timeout_seconds(const int timeout_seconds) { + timeout_seconds_ = timeout_seconds; + ResetTimeout(); +} + +bool Task::TimedOut() { + return timeout_seconds_ && + timeout_time_ && + CurrentTime() >= timeout_time_; +} + +void Task::ResetTimeout() { + int64_t previous_timeout_time = timeout_time_; + bool timeout_allowed = (state_ != STATE_INIT) + && (state_ != STATE_DONE) + && (state_ != STATE_ERROR); + if (timeout_seconds_ && timeout_allowed && !timeout_suspended_) + timeout_time_ = CurrentTime() + + (timeout_seconds_ * kSecToMsec * kMsecTo100ns); + else + timeout_time_ = 0; + + GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); +} + +void Task::ClearTimeout() { + int64_t previous_timeout_time = timeout_time_; + timeout_time_ = 0; + GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); +} + +void Task::SuspendTimeout() { + if (!timeout_suspended_) { + timeout_suspended_ = true; + ResetTimeout(); + } +} + +void Task::ResumeTimeout() { + if (timeout_suspended_) { + timeout_suspended_ = false; + ResetTimeout(); + } +} + +int Task::OnTimeout() { + // by default, we are finished after timing out + return STATE_DONE; +} + +} // namespace rtc diff --git a/chromium/third_party/libjingle_xmpp/task_runner/task.h b/chromium/third_party/libjingle_xmpp/task_runner/task.h new file mode 100644 index 00000000000..55a8cfea7a7 --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/task.h @@ -0,0 +1,175 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_TASK_H__ +#define WEBRTC_BASE_TASK_H__ + +#include <stdint.h> + +#include <string> + +#include "third_party/libjingle_xmpp/task_runner/taskparent.h" +#include "third_party/webrtc/base/sigslot.h" + +///////////////////////////////////////////////////////////////////// +// +// TASK +// +///////////////////////////////////////////////////////////////////// +// +// Task is a state machine infrastructure. States are pushed forward by +// pushing forwards a TaskRunner that holds on to all Tasks. The purpose +// of Task is threefold: +// +// (1) It manages ongoing work on the UI thread. Multitasking without +// threads, keeping it easy, keeping it real. :-) It does this by +// organizing a set of states for each task. When you return from your +// Process*() function, you return an integer for the next state. You do +// not go onto the next state yourself. Every time you enter a state, +// you check to see if you can do anything yet. If not, you return +// STATE_BLOCKED. If you _could_ do anything, do not return +// STATE_BLOCKED - even if you end up in the same state, return +// STATE_mysamestate. When you are done, return STATE_DONE and then the +// task will self-delete sometime afterwards. +// +// (2) It helps you avoid all those reentrancy problems when you chain +// too many triggers on one thread. Basically if you want to tell a task +// to process something for you, you feed your task some information and +// then you Wake() it. Don't tell it to process it right away. If it +// might be working on something as you send it information, you may want +// to have a queue in the task. +// +// (3) Finally it helps manage parent tasks and children. If a parent +// task gets aborted, all the children tasks are too. The nice thing +// about this, for example, is if you have one parent task that +// represents, say, and Xmpp connection, then you can spawn a whole bunch +// of infinite lifetime child tasks and now worry about cleaning them up. +// When the parent task goes to STATE_DONE, the task engine will make +// sure all those children are aborted and get deleted. +// +// Notice that Task has a few built-in states, e.g., +// +// STATE_INIT - the task isn't running yet +// STATE_START - the task is in its first state +// STATE_RESPONSE - the task is in its second state +// STATE_DONE - the task is done +// +// STATE_ERROR - indicates an error - we should audit the error code in +// light of any usage of it to see if it should be improved. When I +// first put down the task stuff I didn't have a good sense of what was +// needed for Abort and Error, and now the subclasses of Task will ground +// the design in a stronger way. +// +// STATE_NEXT - the first undefined state number. (like WM_USER) - you +// can start defining more task states there. +// +// When you define more task states, just override Process(int state) and +// add your own switch statement. If you want to delegate to +// Task::Process, you can effectively delegate to its switch statement. +// No fancy method pointers or such - this is all just pretty low tech, +// easy to debug, and fast. +// +// Also notice that Task has some primitive built-in timeout functionality. +// +// A timeout is defined as "the task stays in STATE_BLOCKED longer than +// timeout_seconds_." +// +// Descendant classes can override this behavior by calling the +// various protected methods to change the timeout behavior. For +// instance, a descendand might call SuspendTimeout() when it knows +// that it isn't waiting for anything that might timeout, but isn't +// yet in the STATE_DONE state. +// + +namespace rtc { + +// Executes a sequence of steps +class Task : public TaskParent { + public: + Task(TaskParent *parent); + ~Task() override; + + int32_t unique_id() { return unique_id_; } + + void Start(); + void Step(); + int GetState() const { return state_; } + bool HasError() const { return (GetState() == STATE_ERROR); } + bool Blocked() const { return blocked_; } + bool IsDone() const { return done_; } + int64_t ElapsedTime(); + + // Called from outside to stop task without any more callbacks + void Abort(bool nowake = false); + + bool TimedOut(); + + int64_t timeout_time() const { return timeout_time_; } + int timeout_seconds() const { return timeout_seconds_; } + void set_timeout_seconds(int timeout_seconds); + + sigslot::signal0<> SignalTimeout; + + // Called inside the task to signal that the task may be unblocked + void Wake(); + + protected: + + enum { + STATE_BLOCKED = -1, + STATE_INIT = 0, + STATE_START = 1, + STATE_DONE = 2, + STATE_ERROR = 3, + STATE_RESPONSE = 4, + STATE_NEXT = 5, // Subclasses which need more states start here and higher + }; + + // Called inside to advise that the task should wake and signal an error + void Error(); + + int64_t CurrentTime(); + + virtual std::string GetStateName(int state) const; + virtual int Process(int state); + virtual void Stop(); + virtual int ProcessStart() = 0; + virtual int ProcessResponse(); + + void ResetTimeout(); + void ClearTimeout(); + + void SuspendTimeout(); + void ResumeTimeout(); + + protected: + virtual int OnTimeout(); + + private: + void Done(); + + int state_; + bool blocked_; + bool done_; + bool aborted_; + bool busy_; + bool error_; + int64_t start_time_; + int64_t timeout_time_; + int timeout_seconds_; + bool timeout_suspended_; + int32_t unique_id_; + + static int32_t unique_id_seed_; +}; + +} // namespace rtc + +#endif // WEBRTC_BASE_TASK_H__ diff --git a/chromium/third_party/libjingle_xmpp/task_runner/task_unittest.cc b/chromium/third_party/libjingle_xmpp/task_runner/task_unittest.cc new file mode 100644 index 00000000000..7408ec4ae22 --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/task_unittest.cc @@ -0,0 +1,542 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#if defined(WEBRTC_POSIX) +#include <sys/time.h> +#endif // WEBRTC_POSIX + +// TODO: Remove this once the cause of sporadic failures in these +// tests is tracked down. +#include <iostream> + +#if defined(WEBRTC_WIN) +#include "third_party/webrtc/base/win32.h" +#endif // WEBRTC_WIN + +#include "third_party/libjingle_xmpp/task_runner/task.h" +#include "third_party/libjingle_xmpp/task_runner/taskrunner.h" +#include "third_party/webrtc/base/arraysize.h" +#include "third_party/webrtc/base/constructormagic.h" +#include "third_party/webrtc/base/gunit.h" +#include "third_party/webrtc/base/thread.h" +#include "third_party/webrtc/base/timeutils.h" +#include "third_party/webrtc_overrides/webrtc/base/logging.h" + +namespace rtc { + +static int64_t GetCurrentTime() { + return TimeMillis() * 10000; +} + +// feel free to change these numbers. Note that '0' won't work, though +#define STUCK_TASK_COUNT 5 +#define HAPPY_TASK_COUNT 20 + +// this is a generic timeout task which, when it signals timeout, will +// include the unique ID of the task in the signal (we don't use this +// in production code because we haven't yet had occasion to generate +// an array of the same types of task) + +class IdTimeoutTask : public Task, public sigslot::has_slots<> { + public: + explicit IdTimeoutTask(TaskParent *parent) : Task(parent) { + SignalTimeout.connect(this, &IdTimeoutTask::OnLocalTimeout); + } + + sigslot::signal1<const int> SignalTimeoutId; + sigslot::signal1<const int> SignalDoneId; + + virtual int ProcessStart() { + return STATE_RESPONSE; + } + + void OnLocalTimeout() { + SignalTimeoutId(unique_id()); + } + + protected: + virtual void Stop() { + SignalDoneId(unique_id()); + Task::Stop(); + } +}; + +class StuckTask : public IdTimeoutTask { + public: + explicit StuckTask(TaskParent *parent) : IdTimeoutTask(parent) {} + virtual int ProcessStart() { + return STATE_BLOCKED; + } +}; + +class HappyTask : public IdTimeoutTask { + public: + explicit HappyTask(TaskParent *parent) : IdTimeoutTask(parent) { + time_to_perform_ = rand() % (STUCK_TASK_COUNT / 2); + } + virtual int ProcessStart() { + if (ElapsedTime() > (time_to_perform_ * 1000 * 10000)) + return STATE_RESPONSE; + else + return STATE_BLOCKED; + } + + private: + int time_to_perform_; +}; + +// simple implementation of a task runner which uses Windows' +// GetSystemTimeAsFileTime() to get the current clock ticks + +class MyTaskRunner : public TaskRunner { + public: + virtual void WakeTasks() { RunTasks(); } + virtual int64_t CurrentTime() { return GetCurrentTime(); } + + bool timeout_change() const { + return timeout_change_; + } + + void clear_timeout_change() { + timeout_change_ = false; + } + protected: + virtual void OnTimeoutChange() { + timeout_change_ = true; + } + bool timeout_change_; +}; + +// +// this unit test is primarily concerned (for now) with the timeout +// functionality in tasks. It works as follows: +// +// * Create a bunch of tasks, some "stuck" (ie., guaranteed to timeout) +// and some "happy" (will immediately finish). +// * Set the timeout on the "stuck" tasks to some number of seconds between +// 1 and the number of stuck tasks +// * Start all the stuck & happy tasks in random order +// * Wait "number of stuck tasks" seconds and make sure everything timed out + +class TaskTest : public sigslot::has_slots<> { + public: + TaskTest() {} + + // no need to delete any tasks; the task runner owns them + ~TaskTest() {} + + void Start() { + // create and configure tasks + for (int i = 0; i < STUCK_TASK_COUNT; ++i) { + stuck_[i].task_ = new StuckTask(&task_runner_); + stuck_[i].task_->SignalTimeoutId.connect(this, + &TaskTest::OnTimeoutStuck); + stuck_[i].timed_out_ = false; + stuck_[i].xlat_ = stuck_[i].task_->unique_id(); + stuck_[i].task_->set_timeout_seconds(i + 1); + LOG(LS_INFO) << "Task " << stuck_[i].xlat_ << " created with timeout " + << stuck_[i].task_->timeout_seconds(); + } + + for (int i = 0; i < HAPPY_TASK_COUNT; ++i) { + happy_[i].task_ = new HappyTask(&task_runner_); + happy_[i].task_->SignalTimeoutId.connect(this, + &TaskTest::OnTimeoutHappy); + happy_[i].task_->SignalDoneId.connect(this, + &TaskTest::OnDoneHappy); + happy_[i].timed_out_ = false; + happy_[i].xlat_ = happy_[i].task_->unique_id(); + } + + // start all the tasks in random order + int stuck_index = 0; + int happy_index = 0; + for (int i = 0; i < STUCK_TASK_COUNT + HAPPY_TASK_COUNT; ++i) { + if ((stuck_index < STUCK_TASK_COUNT) && + (happy_index < HAPPY_TASK_COUNT)) { + if (rand() % 2 == 1) { + stuck_[stuck_index++].task_->Start(); + } else { + happy_[happy_index++].task_->Start(); + } + } else if (stuck_index < STUCK_TASK_COUNT) { + stuck_[stuck_index++].task_->Start(); + } else { + happy_[happy_index++].task_->Start(); + } + } + + for (int i = 0; i < STUCK_TASK_COUNT; ++i) { + std::cout << "Stuck task #" << i << " timeout is " << + stuck_[i].task_->timeout_seconds() << " at " << + stuck_[i].task_->timeout_time() << std::endl; + } + + // just a little self-check to make sure we started all the tasks + ASSERT_EQ(STUCK_TASK_COUNT, stuck_index); + ASSERT_EQ(HAPPY_TASK_COUNT, happy_index); + + // run the unblocked tasks + LOG(LS_INFO) << "Running tasks"; + task_runner_.RunTasks(); + + std::cout << "Start time is " << GetCurrentTime() << std::endl; + + // give all the stuck tasks time to timeout + for (int i = 0; !task_runner_.AllChildrenDone() && i < STUCK_TASK_COUNT; + ++i) { + Thread::Current()->ProcessMessages(1000); + for (int j = 0; j < HAPPY_TASK_COUNT; ++j) { + if (happy_[j].task_) { + happy_[j].task_->Wake(); + } + } + LOG(LS_INFO) << "Polling tasks"; + task_runner_.PollTasks(); + } + + // We see occasional test failures here due to the stuck tasks not having + // timed-out yet, which seems like it should be impossible. To help track + // this down we have added logging of the timing information, which we send + // directly to stdout so that we get it in opt builds too. + std::cout << "End time is " << GetCurrentTime() << std::endl; + } + + void OnTimeoutStuck(const int id) { + LOG(LS_INFO) << "Timed out task " << id; + + int i; + for (i = 0; i < STUCK_TASK_COUNT; ++i) { + if (stuck_[i].xlat_ == id) { + stuck_[i].timed_out_ = true; + stuck_[i].task_ = NULL; + break; + } + } + + // getting a bad ID here is a failure, but let's continue + // running to see what else might go wrong + EXPECT_LT(i, STUCK_TASK_COUNT); + } + + void OnTimeoutHappy(const int id) { + int i; + for (i = 0; i < HAPPY_TASK_COUNT; ++i) { + if (happy_[i].xlat_ == id) { + happy_[i].timed_out_ = true; + happy_[i].task_ = NULL; + break; + } + } + + // getting a bad ID here is a failure, but let's continue + // running to see what else might go wrong + EXPECT_LT(i, HAPPY_TASK_COUNT); + } + + void OnDoneHappy(const int id) { + int i; + for (i = 0; i < HAPPY_TASK_COUNT; ++i) { + if (happy_[i].xlat_ == id) { + happy_[i].task_ = NULL; + break; + } + } + + // getting a bad ID here is a failure, but let's continue + // running to see what else might go wrong + EXPECT_LT(i, HAPPY_TASK_COUNT); + } + + void check_passed() { + EXPECT_TRUE(task_runner_.AllChildrenDone()); + + // make sure none of our happy tasks timed out + for (int i = 0; i < HAPPY_TASK_COUNT; ++i) { + EXPECT_FALSE(happy_[i].timed_out_); + } + + // make sure all of our stuck tasks timed out + for (int i = 0; i < STUCK_TASK_COUNT; ++i) { + EXPECT_TRUE(stuck_[i].timed_out_); + if (!stuck_[i].timed_out_) { + std::cout << "Stuck task #" << i << " timeout is at " + << stuck_[i].task_->timeout_time() << std::endl; + } + } + + std::cout.flush(); + } + + private: + struct TaskInfo { + IdTimeoutTask *task_; + bool timed_out_; + int xlat_; + }; + + MyTaskRunner task_runner_; + TaskInfo stuck_[STUCK_TASK_COUNT]; + TaskInfo happy_[HAPPY_TASK_COUNT]; +}; + +TEST(start_task_test, Timeout) { + TaskTest task_test; + task_test.Start(); + task_test.check_passed(); +} + +// Test for aborting the task while it is running + +class AbortTask : public Task { + public: + explicit AbortTask(TaskParent *parent) : Task(parent) { + set_timeout_seconds(1); + } + + virtual int ProcessStart() { + Abort(); + return STATE_NEXT; + } + private: + RTC_DISALLOW_COPY_AND_ASSIGN(AbortTask); +}; + +class TaskAbortTest : public sigslot::has_slots<> { + public: + TaskAbortTest() {} + + // no need to delete any tasks; the task runner owns them + ~TaskAbortTest() {} + + void Start() { + Task *abort_task = new AbortTask(&task_runner_); + abort_task->SignalTimeout.connect(this, &TaskAbortTest::OnTimeout); + abort_task->Start(); + + // run the task + task_runner_.RunTasks(); + } + + private: + void OnTimeout() { + FAIL() << "Task timed out instead of aborting."; + } + + MyTaskRunner task_runner_; + RTC_DISALLOW_COPY_AND_ASSIGN(TaskAbortTest); +}; + +TEST(start_task_test, Abort) { + TaskAbortTest abort_test; + abort_test.Start(); +} + +// Test for aborting a task to verify that it does the Wake operation +// which gets it deleted. + +class SetBoolOnDeleteTask : public Task { + public: + SetBoolOnDeleteTask(TaskParent *parent, bool *set_when_deleted) + : Task(parent), + set_when_deleted_(set_when_deleted) { + EXPECT_TRUE(NULL != set_when_deleted); + EXPECT_FALSE(*set_when_deleted); + } + + virtual ~SetBoolOnDeleteTask() { + *set_when_deleted_ = true; + } + + virtual int ProcessStart() { + return STATE_BLOCKED; + } + + private: + bool* set_when_deleted_; + RTC_DISALLOW_COPY_AND_ASSIGN(SetBoolOnDeleteTask); +}; + +class AbortShouldWakeTest : public sigslot::has_slots<> { + public: + AbortShouldWakeTest() {} + + // no need to delete any tasks; the task runner owns them + ~AbortShouldWakeTest() {} + + void Start() { + bool task_deleted = false; + Task *task_to_abort = new SetBoolOnDeleteTask(&task_runner_, &task_deleted); + task_to_abort->Start(); + + // Task::Abort() should call TaskRunner::WakeTasks(). WakeTasks calls + // TaskRunner::RunTasks() immediately which should delete the task. + task_to_abort->Abort(); + EXPECT_TRUE(task_deleted); + + if (!task_deleted) { + // avoid a crash (due to referencing a local variable) + // if the test fails. + task_runner_.RunTasks(); + } + } + + private: + void OnTimeout() { + FAIL() << "Task timed out instead of aborting."; + } + + MyTaskRunner task_runner_; + RTC_DISALLOW_COPY_AND_ASSIGN(AbortShouldWakeTest); +}; + +TEST(start_task_test, AbortShouldWake) { + AbortShouldWakeTest abort_should_wake_test; + abort_should_wake_test.Start(); +} + +// Validate that TaskRunner's OnTimeoutChange gets called appropriately +// * When a task calls UpdateTaskTimeout +// * When the next timeout task time, times out +class TimeoutChangeTest : public sigslot::has_slots<> { + public: + TimeoutChangeTest() + : task_count_(arraysize(stuck_tasks_)) {} + + // no need to delete any tasks; the task runner owns them + ~TimeoutChangeTest() {} + + void Start() { + for (int i = 0; i < task_count_; ++i) { + stuck_tasks_[i] = new StuckTask(&task_runner_); + stuck_tasks_[i]->set_timeout_seconds(i + 2); + stuck_tasks_[i]->SignalTimeoutId.connect(this, + &TimeoutChangeTest::OnTimeoutId); + } + + for (int i = task_count_ - 1; i >= 0; --i) { + stuck_tasks_[i]->Start(); + } + task_runner_.clear_timeout_change(); + + // At this point, our timeouts are set as follows + // task[0] is 2 seconds, task[1] at 3 seconds, etc. + + stuck_tasks_[0]->set_timeout_seconds(2); + // Now, task[0] is 2 seconds, task[1] at 3 seconds... + // so timeout change shouldn't be called. + EXPECT_FALSE(task_runner_.timeout_change()); + task_runner_.clear_timeout_change(); + + stuck_tasks_[0]->set_timeout_seconds(1); + // task[0] is 1 seconds, task[1] at 3 seconds... + // The smallest timeout got smaller so timeout change be called. + EXPECT_TRUE(task_runner_.timeout_change()); + task_runner_.clear_timeout_change(); + + stuck_tasks_[1]->set_timeout_seconds(2); + // task[0] is 1 seconds, task[1] at 2 seconds... + // The smallest timeout is still 1 second so no timeout change. + EXPECT_FALSE(task_runner_.timeout_change()); + task_runner_.clear_timeout_change(); + + while (task_count_ > 0) { + int previous_count = task_count_; + task_runner_.PollTasks(); + if (previous_count != task_count_) { + // We only get here when a task times out. When that + // happens, the timeout change should get called because + // the smallest timeout is now in the past. + EXPECT_TRUE(task_runner_.timeout_change()); + task_runner_.clear_timeout_change(); + } + Thread::Current()->socketserver()->Wait(500, false); + } + } + + private: + void OnTimeoutId(const int id) { + for (size_t i = 0; i < arraysize(stuck_tasks_); ++i) { + if (stuck_tasks_[i] && stuck_tasks_[i]->unique_id() == id) { + task_count_--; + stuck_tasks_[i] = NULL; + break; + } + } + } + + MyTaskRunner task_runner_; + StuckTask* (stuck_tasks_[3]); + int task_count_; + RTC_DISALLOW_COPY_AND_ASSIGN(TimeoutChangeTest); +}; + +TEST(start_task_test, TimeoutChange) { + TimeoutChangeTest timeout_change_test; + timeout_change_test.Start(); +} + +class DeleteTestTaskRunner : public TaskRunner { + public: + DeleteTestTaskRunner() { + } + virtual void WakeTasks() { } + virtual int64_t CurrentTime() { return GetCurrentTime(); } + private: + RTC_DISALLOW_COPY_AND_ASSIGN(DeleteTestTaskRunner); +}; + +TEST(unstarted_task_test, DeleteTask) { + // This test ensures that we don't + // crash if a task is deleted without running it. + DeleteTestTaskRunner task_runner; + HappyTask* happy_task = new HappyTask(&task_runner); + happy_task->Start(); + + // try deleting the task directly + HappyTask* child_happy_task = new HappyTask(happy_task); + delete child_happy_task; + + // run the unblocked tasks + task_runner.RunTasks(); +} + +TEST(unstarted_task_test, DoNotDeleteTask1) { + // This test ensures that we don't + // crash if a task runner is deleted without + // running a certain task. + DeleteTestTaskRunner task_runner; + HappyTask* happy_task = new HappyTask(&task_runner); + happy_task->Start(); + + HappyTask* child_happy_task = new HappyTask(happy_task); + child_happy_task->Start(); + + // Never run the tasks +} + +TEST(unstarted_task_test, DoNotDeleteTask2) { + // This test ensures that we don't + // crash if a taskrunner is delete with a + // task that has never been started. + DeleteTestTaskRunner task_runner; + HappyTask* happy_task = new HappyTask(&task_runner); + happy_task->Start(); + + // Do not start the task. + // Note: this leaks memory, so don't do this. + // Instead, always run your tasks or delete them. + new HappyTask(happy_task); + + // run the unblocked tasks + task_runner.RunTasks(); +} + +} // namespace rtc diff --git a/chromium/third_party/libjingle_xmpp/task_runner/taskparent.cc b/chromium/third_party/libjingle_xmpp/task_runner/taskparent.cc new file mode 100644 index 00000000000..d0245ab04ae --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/taskparent.cc @@ -0,0 +1,98 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <algorithm> + +#include "third_party/libjingle_xmpp/task_runner/taskparent.h" + +#include "third_party/libjingle_xmpp/task_runner/taskrunner.h" +#include "third_party/libjingle_xmpp/task_runner/task.h" +#include "third_party/webrtc/base/checks.h" + +namespace rtc { + +TaskParent::TaskParent(Task* derived_instance, TaskParent *parent) + : parent_(parent) { + RTC_DCHECK(derived_instance != NULL); + RTC_DCHECK(parent != NULL); + runner_ = parent->GetRunner(); + parent_->AddChild(derived_instance); + Initialize(); +} + +TaskParent::TaskParent(TaskRunner *derived_instance) + : parent_(NULL), + runner_(derived_instance) { + RTC_DCHECK(derived_instance != NULL); + Initialize(); +} + +TaskParent::~TaskParent() = default; + +// Does common initialization of member variables +void TaskParent::Initialize() { + children_.reset(new ChildSet()); + child_error_ = false; +} + +void TaskParent::AddChild(Task *child) { + children_->insert(child); +} + +#if RTC_DCHECK_IS_ON +bool TaskParent::IsChildTask(Task *task) { + RTC_DCHECK(task != NULL); + return task->parent_ == this && children_->find(task) != children_->end(); +} +#endif + +bool TaskParent::AllChildrenDone() { + for (ChildSet::iterator it = children_->begin(); + it != children_->end(); + ++it) { + if (!(*it)->IsDone()) + return false; + } + return true; +} + +bool TaskParent::AnyChildError() { + return child_error_; +} + +void TaskParent::AbortAllChildren() { + if (children_->size() > 0) { +#if RTC_DCHECK_IS_ON + runner_->IncrementAbortCount(); +#endif + + ChildSet copy = *children_; + for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) { + (*it)->Abort(true); // Note we do not wake + } + +#if RTC_DCHECK_IS_ON + runner_->DecrementAbortCount(); +#endif + } +} + +void TaskParent::OnStopped(Task *task) { + AbortAllChildren(); + parent_->OnChildStopped(task); +} + +void TaskParent::OnChildStopped(Task *child) { + if (child->HasError()) + child_error_ = true; + children_->erase(child); +} + +} // namespace rtc diff --git a/chromium/third_party/libjingle_xmpp/task_runner/taskparent.h b/chromium/third_party/libjingle_xmpp/task_runner/taskparent.h new file mode 100644 index 00000000000..38075dd0d4e --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/taskparent.h @@ -0,0 +1,63 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_TASKPARENT_H__ +#define WEBRTC_BASE_TASKPARENT_H__ + +#include <memory> +#include <set> + +#include "third_party/webrtc/base/checks.h" +#include "third_party/webrtc/base/constructormagic.h" + +namespace rtc { + +class Task; +class TaskRunner; + +class TaskParent { + public: + TaskParent(Task *derived_instance, TaskParent *parent); + explicit TaskParent(TaskRunner *derived_instance); + virtual ~TaskParent(); + + TaskParent *GetParent() { return parent_; } + TaskRunner *GetRunner() { return runner_; } + + bool AllChildrenDone(); + bool AnyChildError(); +#if RTC_DCHECK_IS_ON + bool IsChildTask(Task *task); +#endif + + protected: + void OnStopped(Task *task); + void AbortAllChildren(); + TaskParent *parent() { + return parent_; + } + + private: + void Initialize(); + void OnChildStopped(Task *child); + void AddChild(Task *child); + + TaskParent *parent_; + TaskRunner *runner_; + bool child_error_; + typedef std::set<Task *> ChildSet; + std::unique_ptr<ChildSet> children_; + RTC_DISALLOW_COPY_AND_ASSIGN(TaskParent); +}; + + +} // namespace rtc + +#endif // WEBRTC_BASE_TASKPARENT_H__ diff --git a/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.cc b/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.cc new file mode 100644 index 00000000000..7eae04c926f --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.cc @@ -0,0 +1,217 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <algorithm> + +#include "third_party/libjingle_xmpp/task_runner/taskrunner.h" + +#include "third_party/libjingle_xmpp/task_runner/task.h" +#include "third_party/webrtc/base/checks.h" +#include "third_party/webrtc/base/logging.h" + +namespace rtc { + +TaskRunner::TaskRunner() + : TaskParent(this) {} + +TaskRunner::~TaskRunner() { + // this kills and deletes children silently! + AbortAllChildren(); + InternalRunTasks(true); +} + +void TaskRunner::StartTask(Task * task) { + tasks_.push_back(task); + + // the task we just started could be about to timeout -- + // make sure our "next timeout task" is correct + UpdateTaskTimeout(task, 0); + + WakeTasks(); +} + +void TaskRunner::RunTasks() { + InternalRunTasks(false); +} + +void TaskRunner::InternalRunTasks(bool in_destructor) { + // This shouldn't run while an abort is happening. + // If that occurs, then tasks may be deleted in this method, + // but pointers to them will still be in the + // "ChildSet copy" in TaskParent::AbortAllChildren. + // Subsequent use of those task may cause data corruption or crashes. +#if RTC_DCHECK_IS_ON + RTC_DCHECK(!abort_count_); +#endif + // Running continues until all tasks are Blocked (ok for a small # of tasks) + if (tasks_running_) { + return; // don't reenter + } + + tasks_running_ = true; + + int64_t previous_timeout_time = next_task_timeout(); + + int did_run = true; + while (did_run) { + did_run = false; + // use indexing instead of iterators because tasks_ may grow + for (size_t i = 0; i < tasks_.size(); ++i) { + while (!tasks_[i]->Blocked()) { + tasks_[i]->Step(); + did_run = true; + } + } + } + // Tasks are deleted when running has paused + bool need_timeout_recalc = false; + for (size_t i = 0; i < tasks_.size(); ++i) { + if (tasks_[i]->IsDone()) { + Task* task = tasks_[i]; + if (next_timeout_task_ && + task->unique_id() == next_timeout_task_->unique_id()) { + next_timeout_task_ = NULL; + need_timeout_recalc = true; + } + +#if RTC_DCHECK_IS_ON + deleting_task_ = task; +#endif + delete task; +#if RTC_DCHECK_IS_ON + deleting_task_ = NULL; +#endif + tasks_[i] = NULL; + } + } + // Finally, remove nulls + std::vector<Task *>::iterator it; + it = std::remove(tasks_.begin(), + tasks_.end(), + reinterpret_cast<Task *>(NULL)); + + tasks_.erase(it, tasks_.end()); + + if (need_timeout_recalc) + RecalcNextTimeout(NULL); + + // Make sure that adjustments are done to account + // for any timeout changes (but don't call this + // while being destroyed since it calls a pure virtual function). + if (!in_destructor) + CheckForTimeoutChange(previous_timeout_time); + + tasks_running_ = false; +} + +void TaskRunner::PollTasks() { + // see if our "next potentially timed-out task" has indeed timed out. + // If it has, wake it up, then queue up the next task in line + // Repeat while we have new timed-out tasks. + // TODO: We need to guard against WakeTasks not updating + // next_timeout_task_. Maybe also add documentation in the header file once + // we understand this code better. + Task* old_timeout_task = NULL; + while (next_timeout_task_ && + old_timeout_task != next_timeout_task_ && + next_timeout_task_->TimedOut()) { + old_timeout_task = next_timeout_task_; + next_timeout_task_->Wake(); + WakeTasks(); + } +} + +int64_t TaskRunner::next_task_timeout() const { + if (next_timeout_task_) { + return next_timeout_task_->timeout_time(); + } + return 0; +} + +// this function gets called frequently -- when each task changes +// state to something other than DONE, ERROR or BLOCKED, it calls +// ResetTimeout(), which will call this function to make sure that +// the next timeout-able task hasn't changed. The logic in this function +// prevents RecalcNextTimeout() from getting called in most cases, +// effectively making the task scheduler O-1 instead of O-N + +void TaskRunner::UpdateTaskTimeout(Task* task, + int64_t previous_task_timeout_time) { + RTC_DCHECK(task != NULL); + int64_t previous_timeout_time = next_task_timeout(); + bool task_is_timeout_task = next_timeout_task_ != NULL && + task->unique_id() == next_timeout_task_->unique_id(); + if (task_is_timeout_task) { + previous_timeout_time = previous_task_timeout_time; + } + + // if the relevant task has a timeout, then + // check to see if it's closer than the current + // "about to timeout" task + if (task->timeout_time()) { + if (next_timeout_task_ == NULL || + (task->timeout_time() <= next_timeout_task_->timeout_time())) { + next_timeout_task_ = task; + } + } else if (task_is_timeout_task) { + // otherwise, if the task doesn't have a timeout, + // and it used to be our "about to timeout" task, + // walk through all the tasks looking for the real + // "about to timeout" task + RecalcNextTimeout(task); + } + + // Note when task_running_, then the running routine + // (TaskRunner::InternalRunTasks) is responsible for calling + // CheckForTimeoutChange. + if (!tasks_running_) { + CheckForTimeoutChange(previous_timeout_time); + } +} + +void TaskRunner::RecalcNextTimeout(Task *exclude_task) { + // walk through all the tasks looking for the one + // which satisfies the following: + // it's not finished already + // we're not excluding it + // it has the closest timeout time + + int64_t next_timeout_time = 0; + next_timeout_task_ = NULL; + + for (size_t i = 0; i < tasks_.size(); ++i) { + Task *task = tasks_[i]; + // if the task isn't complete, and it actually has a timeout time + if (!task->IsDone() && (task->timeout_time() > 0)) + // if it doesn't match our "exclude" task + if (exclude_task == NULL || + exclude_task->unique_id() != task->unique_id()) + // if its timeout time is sooner than our current timeout time + if (next_timeout_time == 0 || + task->timeout_time() <= next_timeout_time) { + // set this task as our next-to-timeout + next_timeout_time = task->timeout_time(); + next_timeout_task_ = task; + } + } +} + +void TaskRunner::CheckForTimeoutChange(int64_t previous_timeout_time) { + int64_t next_timeout = next_task_timeout(); + bool timeout_change = (previous_timeout_time == 0 && next_timeout != 0) || + next_timeout < previous_timeout_time || + (previous_timeout_time <= CurrentTime() && + previous_timeout_time != next_timeout); + if (timeout_change) { + OnTimeoutChange(); + } +} + +} // namespace rtc diff --git a/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.h b/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.h new file mode 100644 index 00000000000..44ac9942072 --- /dev/null +++ b/chromium/third_party/libjingle_xmpp/task_runner/taskrunner.h @@ -0,0 +1,102 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_TASKRUNNER_H__ +#define WEBRTC_BASE_TASKRUNNER_H__ + +#include <stdint.h> + +#include <vector> + +#include "third_party/libjingle_xmpp/task_runner/taskparent.h" +#include "third_party/webrtc/base/checks.h" +#include "third_party/webrtc/base/sigslot.h" + +namespace rtc { +class Task; + +const int64_t kSecToMsec = 1000; +const int64_t kMsecTo100ns = 10000; +const int64_t kSecTo100ns = kSecToMsec * kMsecTo100ns; + +class TaskRunner : public TaskParent, public sigslot::has_slots<> { + public: + TaskRunner(); + ~TaskRunner() override; + + virtual void WakeTasks() = 0; + + // Returns the current time in 100ns units. It is used for + // determining timeouts. The origin is not important, only + // the units and that rollover while the computer is running. + // + // On Windows, GetSystemTimeAsFileTime is the typical implementation. + virtual int64_t CurrentTime() = 0; + + void StartTask(Task *task); + void RunTasks(); + void PollTasks(); + + void UpdateTaskTimeout(Task* task, int64_t previous_task_timeout_time); + +#if RTC_DCHECK_IS_ON + bool is_ok_to_delete(Task* task) { + return task == deleting_task_; + } + + void IncrementAbortCount() { + ++abort_count_; + } + + void DecrementAbortCount() { + --abort_count_; + } +#endif + + // Returns the next absolute time when a task times out + // OR "0" if there is no next timeout. + int64_t next_task_timeout() const; + + protected: + // The primary usage of this method is to know if + // a callback timer needs to be set-up or adjusted. + // This method will be called + // * when the next_task_timeout() becomes a smaller value OR + // * when next_task_timeout() has changed values and the previous + // value is in the past. + // + // If the next_task_timeout moves to the future, this method will *not* + // get called (because it subclass should check next_task_timeout() + // when its timer goes off up to see if it needs to set-up a new timer). + // + // Note that this maybe called conservatively. In that it may be + // called when no time change has happened. + virtual void OnTimeoutChange() { + // by default, do nothing. + } + + private: + void InternalRunTasks(bool in_destructor); + void CheckForTimeoutChange(int64_t previous_timeout_time); + + std::vector<Task *> tasks_; + Task *next_timeout_task_ = nullptr; + bool tasks_running_ = false; +#if RTC_DCHECK_IS_ON + int abort_count_ = 0; + Task* deleting_task_ = nullptr; +#endif + + void RecalcNextTimeout(Task *exclude_task); +}; + +} // namespace rtc + +#endif // TASK_BASE_TASKRUNNER_H__ diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc index 68ef3d5ae7f..4ad53318971 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc @@ -14,7 +14,6 @@ #include <vector> #include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" -#include "third_party/webrtc/base/common.h" namespace buzz { @@ -90,8 +89,6 @@ XmlBuilder::StartElement(XmlParseContext * pctx, void XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) { - RTC_UNUSED(pctx); - RTC_UNUSED(name); pelCurrent_ = pvParents_->back(); pvParents_->pop_back(); } @@ -99,7 +96,6 @@ XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) { void XmlBuilder::CharacterData(XmlParseContext * pctx, const char * text, int len) { - RTC_UNUSED(pctx); if (pelCurrent_) { pelCurrent_->AddParsedText(text, len); } @@ -107,8 +103,6 @@ XmlBuilder::CharacterData(XmlParseContext * pctx, void XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) { - RTC_UNUSED(pctx); - RTC_UNUSED(err); pelRoot_.reset(NULL); pelCurrent_ = NULL; pvParents_->clear(); diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc index 0a6f6066e95..2d5d0f2f4aa 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc @@ -14,7 +14,6 @@ #include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/libjingle_xmpp/xmllite/xmlparser.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::XmlBuilder; @@ -174,4 +173,3 @@ TEST(XmlBuilderTest, TestAttrCollision3) { "</testing>"); EXPECT_TRUE(NULL == builder.BuiltElement()); } - diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlelement.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlelement.cc index 0ef58415f52..6cdb920e160 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlelement.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlelement.cc @@ -20,7 +20,7 @@ #include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" #include "third_party/libjingle_xmpp/xmllite/xmlparser.h" #include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" -#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/checks.h" namespace buzz { @@ -358,7 +358,7 @@ void XmlElement::RemoveChildAfter(XmlChild* predecessor) { } void XmlElement::AddAttr(const QName& name, const std::string& value) { - ASSERT(!HasAttr(name)); + RTC_DCHECK(!HasAttr(name)); XmlAttr ** pprev = last_attr_ ? &(last_attr_->next_attr_) : &first_attr_; last_attr_ = (*pprev = new XmlAttr(name, value)); diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc index f54ae95f530..c74c23655d1 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc @@ -12,7 +12,6 @@ #include <sstream> #include <string> #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" #include "third_party/webrtc/base/thread.h" diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc index 19372a600ef..5a0e6a2a555 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc @@ -15,7 +15,6 @@ #include <string> #include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::NS_XML; diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlparser.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlparser.cc index 1f8153f1891..2f1d9aebd43 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlparser.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlparser.cc @@ -17,7 +17,6 @@ #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" #include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" -#include "third_party/webrtc/base/common.h" namespace buzz { diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc index a0a61013a36..1d1e9ca4b2e 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc @@ -13,7 +13,6 @@ #include <string> #include "third_party/libjingle_xmpp/xmllite/qname.h" #include "third_party/libjingle_xmpp/xmllite/xmlparser.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::QName; @@ -34,17 +33,13 @@ class XmlParserTestHandler : public XmlParseHandler { ss_ << ") "; } virtual void EndElement(XmlParseContext * pctx, const char * name) { - RTC_UNUSED(pctx); - RTC_UNUSED(name); ss_ << "END "; } virtual void CharacterData(XmlParseContext * pctx, const char * text, int len) { - RTC_UNUSED(pctx); ss_ << "TEXT (" << std::string(text, len) << ") "; } virtual void Error(XmlParseContext * pctx, XML_Error code) { - RTC_UNUSED(pctx); ss_ << "ERROR (" << static_cast<int>(code) << ") "; } virtual ~XmlParserTestHandler() { diff --git a/chromium/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc b/chromium/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc index f40491d04b2..5b52731cbc7 100644 --- a/chromium/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc @@ -16,7 +16,6 @@ #include "third_party/libjingle_xmpp/xmllite/qname.h" #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::QName; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/asyncsocket.h b/chromium/third_party/libjingle_xmpp/xmpp/asyncsocket.h index b4f31e52129..9bd9b71ca3a 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/asyncsocket.h +++ b/chromium/third_party/libjingle_xmpp/xmpp/asyncsocket.h @@ -28,10 +28,8 @@ public: STATE_CLOSING, //!< Socket is closing but can have buffered data STATE_CONNECTING, //!< In the process of STATE_OPEN, //!< Socket is connected -#if defined(FEATURE_ENABLE_SSL) STATE_TLS_CONNECTING, //!< Establishing TLS connection STATE_TLS_OPEN, //!< TLS connected -#endif }; enum Error { @@ -39,9 +37,7 @@ public: ERROR_WINSOCK, //!< Winsock error ERROR_DNS, //!< Couldn't resolve host name ERROR_WRONGSTATE, //!< Call made while socket is in the wrong state -#if defined(FEATURE_ENABLE_SSL) ERROR_SSL, //!< Something went wrong with OpenSSL -#endif }; virtual ~AsyncSocket() {} @@ -53,12 +49,10 @@ public: virtual bool Read(char * data, size_t len, size_t* len_read) = 0; virtual bool Write(const char * data, size_t len) = 0; virtual bool Close() = 0; -#if defined(FEATURE_ENABLE_SSL) // We allow matching any passed domain. This allows us to avoid // handling the valuable certificates for logins into proxies. If // both names are passed as empty, we do not require a match. virtual bool StartTls(const std::string & domainname) = 0; -#endif sigslot::signal0<> SignalConnected; sigslot::signal0<> SignalSSLConnected; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/constants.cc b/chromium/third_party/libjingle_xmpp/xmpp/constants.cc index 2d4c039a601..cd0cef2fa9b 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/constants.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/constants.cc @@ -76,10 +76,8 @@ const char STR_TALKX_L_GOOGLE_COM[] = "talkx.l.google.com"; const char STR_XMPP_GOOGLE_COM[] = "xmpp.google.com"; const char STR_XMPPX_L_GOOGLE_COM[] = "xmppx.l.google.com"; -#ifdef FEATURE_ENABLE_VOICEMAIL const char STR_VOICEMAIL[] = "voicemail"; const char STR_OUTGOINGVOICEMAIL[] = "outgoingvoicemail"; -#endif const char STR_UNAVAILABLE[] = "unavailable"; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/constants.h b/chromium/third_party/libjingle_xmpp/xmpp/constants.h index dad55bf871a..16bed975684 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/constants.h +++ b/chromium/third_party/libjingle_xmpp/xmpp/constants.h @@ -71,10 +71,8 @@ extern const char STR_TALKX_L_GOOGLE_COM[]; extern const char STR_XMPP_GOOGLE_COM[]; extern const char STR_XMPPX_L_GOOGLE_COM[]; -#ifdef FEATURE_ENABLE_VOICEMAIL extern const char STR_VOICEMAIL[]; extern const char STR_OUTGOINGVOICEMAIL[]; -#endif extern const char STR_UNAVAILABLE[]; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/jid.cc b/chromium/third_party/libjingle_xmpp/xmpp/jid.cc index 53f7f8a9dcd..032ce03a809 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/jid.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/jid.cc @@ -16,7 +16,7 @@ #include <string> #include "third_party/libjingle_xmpp/xmpp/constants.h" -#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/checks.h" #include "third_party/webrtc_overrides/webrtc/base/logging.h" namespace buzz { @@ -85,7 +85,7 @@ std::string Jid::Str() const { if (!node_name_.empty()) ret = node_name_ + "@"; - ASSERT(domain_name_ != STR_EMPTY); + RTC_DCHECK(domain_name_ != STR_EMPTY); ret += domain_name_; if (!resource_name_.empty()) diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppclient.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppclient.cc index c8b0265eeea..4860b5b5232 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppclient.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppclient.cc @@ -394,9 +394,7 @@ void XmppClient::Private::WriteOutput(const char* bytes, size_t len) { } void XmppClient::Private::StartTls(const std::string& domain) { -#if defined(FEATURE_ENABLE_SSL) socket_->StartTls(domain); -#endif } void XmppClient::Private::CloseConnection() { diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc index 93c8189a03f..5b9ff966ec2 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc @@ -19,7 +19,6 @@ #include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" #include "third_party/libjingle_xmpp/xmpp/util_unittest.h" #include "third_party/libjingle_xmpp/xmpp/xmppengine.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::Jid; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc index 8ba57a642cc..882bf36073a 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc @@ -19,7 +19,7 @@ #include "third_party/libjingle_xmpp/xmpp/constants.h" #include "third_party/libjingle_xmpp/xmpp/saslhandler.h" #include "third_party/libjingle_xmpp/xmpp/xmpplogintask.h" -#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/checks.h" namespace buzz { @@ -347,7 +347,7 @@ void XmppEngineImpl::InternalSendStanza(const XmlElement* element) { // It should really never be necessary to set a FROM attribute on a stanza. // It is implied by the bind on the stream and if you get it wrong // (by flipping from/to on a message?) the server will close the stream. - ASSERT(!element->HasAttr(QN_FROM)); + RTC_DCHECK(!element->HasAttr(QN_FROM)); XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_); } diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc index a5b57146b96..e206678ba1a 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc @@ -12,7 +12,6 @@ #include <vector> #include "third_party/libjingle_xmpp/xmpp/constants.h" #include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h" -#include "third_party/webrtc/base/common.h" namespace buzz { diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc index 6936b77fd2e..ae19b99e4b4 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc @@ -19,7 +19,6 @@ #include "third_party/libjingle_xmpp/xmpp/saslmechanism.h" #include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h" #include "third_party/webrtc/base/base64.h" -#include "third_party/webrtc/base/common.h" using rtc::ConstantLabel; diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc index 2a70faeefe1..17bced53b75 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc @@ -19,7 +19,6 @@ #include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" #include "third_party/libjingle_xmpp/xmpp/util_unittest.h" #include "third_party/libjingle_xmpp/xmpp/xmppengine.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/cryptstring.h" #include "third_party/webrtc/base/gunit.h" #include "third_party/webrtc/typedefs.h" @@ -634,4 +633,3 @@ TEST_F(XmppLoginTaskTest, TestStreamError) { SetUp(); } } - diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc index 278b98849fe..a42a1b87516 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc @@ -12,7 +12,6 @@ #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/libjingle_xmpp/xmpp/constants.h" -#include "third_party/webrtc/base/common.h" #ifdef EXPAT_RELATIVE_PATH #include "expat.h" #else @@ -81,8 +80,6 @@ XmppStanzaParser::IncomingEndElement( void XmppStanzaParser::IncomingError( XmlParseContext * pctx, XML_Error errCode) { - RTC_UNUSED(pctx); - RTC_UNUSED(errCode); psph_->XmlError(); } diff --git a/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc b/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc index 109701b3265..2e9b9f58afa 100644 --- a/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc +++ b/chromium/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc @@ -13,7 +13,6 @@ #include <string> #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h" -#include "third_party/webrtc/base/common.h" #include "third_party/webrtc/base/gunit.h" using buzz::QName; |