Files
platform-external-webrtc/test/single_threaded_task_queue.h
Danil Chapovalov 71037a8e99 Implement TaskQueueBase interface by SingleThreadedTaskQueueForTesting
that allows to use SingleThreadedTaskQueueForTesting as regular TaskQueue.
which allows components that currently depend on SingleThreadedTaskQueueForTesting
to depend on TaskQueueBase interface instead.
Those updates can be done one-by-one and in the end would allow to stop
using SingleThreadedTaskQueueForTesting in favor of other TaskQueue implementations.

Bug: webrtc:10933
Change-Id: I3e642c88c968012588b9d9c09918340f37bbedbd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154352
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Yves Gerey <yvesg@google.com>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29307}
2019-09-25 15:58:17 +00:00

138 lines
4.8 KiB
C++

/*
* Copyright (c) 2017 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 TEST_SINGLE_THREADED_TASK_QUEUE_H_
#define TEST_SINGLE_THREADED_TASK_QUEUE_H_
#include <functional>
#include <map>
#include <memory>
#include "api/task_queue/task_queue_base.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/deprecation.h"
#include "rtc_base/event.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/thread_checker.h"
namespace webrtc {
namespace test {
// DEPRECATED. This class doesn't striclty follow rtc::TaskQueue semantics,
// which makes it surprising and hard to use correctly.
// Please use TaskQueueForTest instead.
// This class gives capabilities similar to rtc::TaskQueue, but ensures
// everything happens on the same thread. This is intended to make the
// threading model of unit-tests (specifically end-to-end tests) more closely
// resemble that of real WebRTC, thereby allowing us to replace some critical
// sections by thread-checkers.
// This task is NOT tuned for performance, but rather for simplicity.
class DEPRECATED_SingleThreadedTaskQueueForTesting : public TaskQueueBase {
public:
using Task = std::function<void()>;
using TaskId = size_t;
constexpr static TaskId kInvalidTaskId = static_cast<TaskId>(-1);
explicit DEPRECATED_SingleThreadedTaskQueueForTesting(const char* name);
~DEPRECATED_SingleThreadedTaskQueueForTesting() override;
// Sends one task to the task-queue, and returns a handle by which the
// task can be cancelled.
// This mimics the behavior of TaskQueue, but only for lambdas, rather than
// for both lambdas and QueuedTask objects.
TaskId PostTask(Task task) {
return PostDelayed(ToQueuedTask(std::move(task)), /*delay_ms=*/0);
}
// Same as PostTask(), but ensures that the task will not begin execution
// less than |delay_ms| milliseconds after being posted; an upper bound
// is not provided.
TaskId PostDelayedTask(Task task, int64_t delay_ms) {
return PostDelayed(ToQueuedTask(std::move(task)), delay_ms);
}
// Send one task to the queue. The function does not return until the task
// has finished executing. No support for canceling the task.
void SendTask(Task task);
// Given an identifier to the task, attempts to eject it from the queue.
// Returns true if the task was found and cancelled. Failure possible
// only for invalid task IDs, or for tasks which have already been executed.
bool CancelTask(TaskId task_id);
// Returns true iff called on the thread associated with the task queue.
bool IsCurrent();
// Returns true iff the task queue is actively being serviced.
bool IsRunning();
bool HasPendingTasks() const;
void Stop();
// Implements TaskQueueBase.
void Delete() override;
void PostTask(std::unique_ptr<QueuedTask> task) override {
PostDelayed(std::move(task), /*delay_ms=*/0);
}
void PostDelayedTask(std::unique_ptr<QueuedTask> task,
uint32_t delay_ms) override {
PostDelayed(std::move(task), delay_ms);
}
private:
struct StoredTask {
StoredTask(TaskId task_id, std::unique_ptr<QueuedTask> task);
~StoredTask();
TaskId task_id;
std::unique_ptr<QueuedTask> task;
};
TaskId PostDelayed(std::unique_ptr<QueuedTask> task, int64_t delay_ms);
static void Run(void* obj);
void RunLoop();
rtc::CriticalSection cs_;
// Tasks are ordered by earliest execution time.
std::multimap<int64_t, StoredTask> tasks_ RTC_GUARDED_BY(cs_);
rtc::ThreadChecker owner_thread_checker_;
rtc::PlatformThread thread_;
bool running_ RTC_GUARDED_BY(cs_);
TaskId next_task_id_;
// The task-queue will sleep when not executing a task. Wake up occurs when:
// * Upon destruction, to make sure that the |thead_| terminates, so that it
// may be joined. [Event will be set.]
// * New task added. Because we optimize for simplicity rahter than for
// performance (this class is a testing facility only), waking up occurs
// when we get a new task even if it is scheduled with a delay. The RunLoop
// is in charge of sending itself back to sleep if the next task is only
// to be executed at a later time. [Event will be set.]
// * When the next task in the queue is a delayed-task, and the time for
// its execution has come. [Event will time-out.]
rtc::Event wake_up_;
};
// Warn if new usage.
typedef DEPRECATED_SingleThreadedTaskQueueForTesting RTC_DEPRECATED
SingleThreadedTaskQueueForTesting;
} // namespace test
} // namespace webrtc
#endif // TEST_SINGLE_THREADED_TASK_QUEUE_H_