Fix DCHECK of SimpleThread on invalid command line options

- Construct SimpleThreads only after all workers have been successfully
  initialized

b/72999680

Change-Id: I4016321a4bdd27b1de746c50c5f1d7a60d7ae9f1
This commit is contained in:
KongQun Yang 2018-02-06 11:47:41 -08:00
parent c7eb2b4a7e
commit 2d5e2b0903
3 changed files with 27 additions and 17 deletions

View File

@ -14,14 +14,10 @@ namespace media {
Job::Job(const std::string& name, std::shared_ptr<OriginHandler> work) Job::Job(const std::string& name, std::shared_ptr<OriginHandler> work)
: SimpleThread(name), : SimpleThread(name),
work_(work), work_(std::move(work)),
wait_(base::WaitableEvent::ResetPolicy::MANUAL, wait_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED) { base::WaitableEvent::InitialState::NOT_SIGNALED) {
DCHECK(work); DCHECK(work_);
}
void Job::Initialize() {
status_ = work_->Initialize();
} }
void Job::Cancel() { void Job::Cancel() {
@ -35,17 +31,22 @@ void Job::Run() {
void JobManager::Add(const std::string& name, void JobManager::Add(const std::string& name,
std::shared_ptr<OriginHandler> handler) { std::shared_ptr<OriginHandler> handler) {
jobs_.emplace_back(new Job(name, std::move(handler))); // Stores Job entries for delayed construction of Job objects, to avoid
// setting up SimpleThread until we know all workers can be initialized
// successfully.
job_entries_.push_back({name, std::move(handler)});
} }
Status JobManager::InitializeJobs() { Status JobManager::InitializeJobs() {
Status status; Status status;
for (const JobEntry& job_entry : job_entries_)
status.Update(job_entry.worker->Initialize());
if (!status.ok())
return status;
for (auto& job : jobs_) { // Create Job objects after successfully initialized all workers.
job->Initialize(); for (const JobEntry& job_entry : job_entries_)
status.Update(job->status()); jobs_.emplace_back(new Job(job_entry.name, std::move(job_entry.worker)));
}
return status; return status;
} }

View File

@ -24,11 +24,6 @@ class Job : public base::SimpleThread {
public: public:
Job(const std::string& name, std::shared_ptr<OriginHandler> work); Job(const std::string& name, std::shared_ptr<OriginHandler> work);
// Initialize the chain of handlers that make up this job. This only
// initializes the handlers, it does not execute the job. If
// initialization fails, |status| will return a non-ok status.
void Initialize();
// Request that the job stops executing. This is only a request and // 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 // will not block. If you want to wait for the job to complete, use
// |wait|. // |wait|.
@ -84,6 +79,12 @@ class JobManager {
JobManager(const JobManager&) = delete; JobManager(const JobManager&) = delete;
JobManager& operator=(const JobManager&) = delete; JobManager& operator=(const JobManager&) = delete;
struct JobEntry {
std::string name;
std::shared_ptr<OriginHandler> worker;
};
// Stores Job entries for delayed construction of Job object.
std::vector<JobEntry> job_entries_;
std::vector<std::unique_ptr<Job>> jobs_; std::vector<std::unique_ptr<Job>> jobs_;
}; };

View File

@ -1415,6 +1415,14 @@ class PackagerCommandParsingTest(PackagerAppTest):
self._GetStreams(['audio', 'video']), flags) self._GetStreams(['audio', 'video']), flags)
self.assertEqual(packaging_result, 1) self.assertEqual(packaging_result, 1)
def testPackageAudioVideoWithNotExistText(self):
audio_video_stream = self._GetStreams(['audio', 'video'])
text_stream = self._GetStreams(['text'], test_files=['not-exist.vtt'])
packaging_result = self.packager.Package(audio_video_stream + text_stream,
self._GetFlags())
# Expect the test to fail but we do not expect a crash.
self.assertEqual(packaging_result, 1)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()