2023-12-01 17:32:19 +00:00
|
|
|
// Copyright 2017 Google LLC. All rights reserved.
|
2017-12-12 21:05:12 +00:00
|
|
|
//
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file or at
|
|
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
|
|
|
|
#ifndef PACKAGER_APP_JOB_MANAGER_H_
|
|
|
|
#define PACKAGER_APP_JOB_MANAGER_H_
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
#include <functional>
|
|
|
|
#include <map>
|
2017-12-12 21:05:12 +00:00
|
|
|
#include <memory>
|
2023-12-01 17:32:19 +00:00
|
|
|
#include <thread>
|
2017-12-12 21:05:12 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
#include <absl/synchronization/mutex.h>
|
|
|
|
|
|
|
|
#include <packager/status.h>
|
2017-12-12 21:05:12 +00:00
|
|
|
|
|
|
|
namespace shaka {
|
|
|
|
namespace media {
|
|
|
|
|
|
|
|
class OriginHandler;
|
2018-03-22 06:24:17 +00:00
|
|
|
class SyncPointQueue;
|
2017-12-12 21:05:12 +00:00
|
|
|
|
|
|
|
// A job is a single line of work that is expected to run in parallel with
|
|
|
|
// other jobs.
|
2023-12-01 17:32:19 +00:00
|
|
|
class Job {
|
2017-12-12 21:05:12 +00:00
|
|
|
public:
|
2023-12-01 17:32:19 +00:00
|
|
|
typedef std::function<void(Job*)> OnCompleteFunction;
|
|
|
|
|
|
|
|
Job(const std::string& name,
|
|
|
|
std::shared_ptr<OriginHandler> work,
|
|
|
|
OnCompleteFunction on_complete);
|
|
|
|
|
|
|
|
// Initialize the work object. Call before Start() or Run(). Updates status()
|
|
|
|
// and returns it for convenience.
|
|
|
|
const Status& Initialize();
|
|
|
|
|
|
|
|
// Begin the job in a new thread. This is only a request and will not block.
|
|
|
|
// If you want to wait for the job to complete, use |complete|.
|
|
|
|
// Use either Start() for threaded operation or Run() for non-threaded
|
|
|
|
// operation. DO NOT USE BOTH!
|
|
|
|
void Start();
|
|
|
|
|
|
|
|
// Run the job's work synchronously, blocking until complete. Updates status()
|
|
|
|
// and returns it for convenience.
|
|
|
|
// Use either Start() for threaded operation or Run() for non-threaded
|
|
|
|
// operation. DO NOT USE BOTH!
|
|
|
|
const Status& Run();
|
|
|
|
|
|
|
|
// Request that the job stops executing. This is only a request and will not
|
|
|
|
// block. If you want to wait for the job to complete, use |complete|.
|
2017-12-12 21:05:12 +00:00
|
|
|
void Cancel();
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
// Join the thread, if any was started. Blocks until the thread has stopped.
|
|
|
|
void Join();
|
|
|
|
|
|
|
|
// Get the current status of the job. If the job failed to initialize or
|
|
|
|
// encountered an error during execution this will return the error.
|
2017-12-12 21:05:12 +00:00
|
|
|
const Status& status() const { return status_; }
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
// The name given to this job in the constructor.
|
|
|
|
const std::string& name() const { return name_; }
|
2017-12-12 21:05:12 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Job(const Job&) = delete;
|
|
|
|
Job& operator=(const Job&) = delete;
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
std::string name_;
|
2017-12-12 21:05:12 +00:00
|
|
|
std::shared_ptr<OriginHandler> work_;
|
2023-12-01 17:32:19 +00:00
|
|
|
OnCompleteFunction on_complete_;
|
|
|
|
std::unique_ptr<std::thread> thread_;
|
2017-12-12 21:05:12 +00:00
|
|
|
Status status_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Similar to a thread pool, JobManager manages multiple jobs that are expected
|
|
|
|
// to run in parallel. It can be used to register, run, and stop a batch of
|
|
|
|
// jobs.
|
|
|
|
class JobManager {
|
|
|
|
public:
|
2018-03-22 06:24:17 +00:00
|
|
|
// @param sync_points is an optional SyncPointQueue used to synchronize and
|
|
|
|
// align cue points. JobManager cancels @a sync_points when any job
|
|
|
|
// fails or is cancelled. It can be NULL.
|
|
|
|
explicit JobManager(std::unique_ptr<SyncPointQueue> sync_points);
|
2017-12-12 21:05:12 +00:00
|
|
|
|
2020-10-20 21:08:46 +00:00
|
|
|
virtual ~JobManager() = default;
|
|
|
|
|
2017-12-12 21:05:12 +00:00
|
|
|
// Create a new job entry by specifying the origin handler at the top of the
|
|
|
|
// chain and a name for the thread. This will only register the job. To start
|
|
|
|
// the job, you need to call |RunJobs|.
|
|
|
|
void Add(const std::string& name, std::shared_ptr<OriginHandler> handler);
|
|
|
|
|
|
|
|
// Initialize all registered jobs. If any job fails to initialize, this will
|
|
|
|
// return the error and it will not be safe to call |RunJobs| as not all jobs
|
|
|
|
// will be properly initialized.
|
2023-12-01 17:32:19 +00:00
|
|
|
Status InitializeJobs();
|
2017-12-12 21:05:12 +00:00
|
|
|
|
|
|
|
// Run all registered jobs. Before calling this make sure that
|
|
|
|
// |InitializedJobs| returned |Status::OK|. This call is blocking and will
|
|
|
|
// block until all jobs exit.
|
2020-10-20 21:08:46 +00:00
|
|
|
virtual Status RunJobs();
|
2017-12-12 21:05:12 +00:00
|
|
|
|
|
|
|
// Ask all jobs to stop running. This call is non-blocking and can be used to
|
|
|
|
// unblock a call to |RunJobs|.
|
|
|
|
void CancelJobs();
|
|
|
|
|
2018-03-22 06:24:17 +00:00
|
|
|
SyncPointQueue* sync_points() { return sync_points_.get(); }
|
|
|
|
|
2020-10-20 21:08:46 +00:00
|
|
|
protected:
|
2017-12-12 21:05:12 +00:00
|
|
|
JobManager(const JobManager&) = delete;
|
|
|
|
JobManager& operator=(const JobManager&) = delete;
|
|
|
|
|
2023-12-01 17:32:19 +00:00
|
|
|
void OnJobComplete(Job* job);
|
|
|
|
|
2018-03-22 06:24:17 +00:00
|
|
|
// Stored in JobManager so JobManager can cancel |sync_points| when any job
|
|
|
|
// fails or is cancelled.
|
|
|
|
std::unique_ptr<SyncPointQueue> sync_points_;
|
2023-12-01 17:32:19 +00:00
|
|
|
|
|
|
|
std::vector<std::unique_ptr<Job>> jobs_;
|
|
|
|
|
|
|
|
absl::Mutex mutex_;
|
|
|
|
std::map<Job*, bool> complete_ ABSL_GUARDED_BY(mutex_);
|
|
|
|
absl::CondVar any_job_complete_ ABSL_GUARDED_BY(mutex_);
|
2017-12-12 21:05:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace media
|
|
|
|
} // namespace shaka
|
|
|
|
|
|
|
|
#endif // PACKAGER_APP_JOB_MANAGER_H_
|