Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: base/worker_pool_job.h

Issue 5710002: Create base::WorkerPoolJob. Use it for HostResolverImpl and DirectoryLister. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_WORKER_POOL_JOB_H_
6 #define BASE_WORKER_POOL_JOB_H_
7 #pragma once
8
9 #include "base/basictypes.h"
10 #include "base/lock.h"
11 #include "base/message_loop_proxy.h"
12 #include "base/ref_counted.h"
13 #include "base/thread_checker.h"
14
15 namespace base {
16
17 // WARNING: Are you sure you want to use WorkerPool in the first place? The
18 // thread will _not_ be joined, so the job may still be running during shutdown.
19 // Global objects that are deleted by AtExitManager should not be accessed on
20 // the WorkerPool thread, otherwise there is potential for shutdown crashes.
21 //
22 // WorkerPoolJob is a helper class for implementing jobs that get created on an
23 // origin thread, get posted to run on a WorkerPool thread, and then run back on
24 // the origin thread upon completion. WorkerPoolJob also handles cancellation
25 // of a job which prevents it from calling back. Note that we use inheritance
26 // rather than composition here, since WorkerPoolJob also handles lifetime
27 // management via refcounting.
28 class WorkerPoolJob : public base::RefCountedThreadSafe<WorkerPoolJob> {
29 public:
30 // ScopedHandle is provided to automate cancellation of the WorkerPoolJob.
31 template <typename JobType>
32 class ScopedHandle {
33 public:
34 explicit ScopedHandle(JobType* job) : job_(job) {}
35
36 ~ScopedHandle() {
37 if (!job_->canceled() && job_->state_ == RUNNING)
38 job_->CancelJob();
39 }
40
41 JobType* job() const { return job_.get(); }
42
43 private:
44 const scoped_refptr<JobType> job_;
45 DISALLOW_COPY_AND_ASSIGN(ScopedHandle);
46 };
47
48 protected:
49 WorkerPoolJob();
50
51 // This may be deleted on the origin or worker thread.
52 virtual ~WorkerPoolJob();
53
54 // Starts the job. Will post itself to the WorkerPool, where it will invoke
55 // RunJob(). After RunJob() runs, it will post itself back to the origin
56 // thread, where it will invoke OnJobCompleted(). This can only be called
57 // once and must be called on the origin thread.
58 void StartJob();
59
60 // Cancels the job. OnJobCompleted() is guaranteed not to be called when this
61 // happens. May only be called once, and only on the origin thread.
62 void CancelJob();
63
64 // Returns true if CancelJob() has been called.
65 bool canceled() const;
66
67 // NOTE(willchan): I've restricted this to unit tests only, primarily because
68 // I haven't found a good reason for allowing subtypes to access this. If
69 // there is a motivating reason to do so, I am open to it.
70 #if defined(UNIT_TEST)
71 scoped_refptr<MessageLoopProxy> origin_loop() const {
72 return origin_loop_;
73 }
74
75 // Returns true if OnJobCompleted() has not been called yet.
76 bool is_running() const {
77 DCHECK(thread_checker_.CalledOnValidThread());
78 DCHECK_NE(state_, NONE);
79 return state_ == RUNNING;
80 }
81 #endif // defined(UNIT_TEST)
82
83 private:
84 friend class base::RefCountedThreadSafe<WorkerPoolJob>;
85
86 // State machine, primarily for enforcing that certain events only happen
87 // once. Also lets us implement is_running().
88 enum State {
89 NONE,
90 RUNNING,
91 DONE,
92 };
93
94 // API for subtypes to implement.
95
96 // RunJob() runs on the worker thread. If CancelJob() is called on the origin
97 // thread , then it may never be invoked, but that's a race.
98 virtual void RunJob() = 0;
99
100 // OnJobCompleted() runs on the origin thread. If CancelJob() is called, then
101 // it may never be invoked.
eroman 2011/01/05 01:24:52 This wording can be stronger. If CancelJob() was c
102 virtual void OnJobCompleted() = 0;
103
104 void RunJobOnWorkerPool();
105 void CompleteJobOnOriginLoop();
106
107 ThreadChecker thread_checker_;
108 const scoped_refptr<MessageLoopProxy> origin_loop_;
109
110 bool canceled_;
111 State state_;
112
113 DISALLOW_COPY_AND_ASSIGN(WorkerPoolJob);
114 };
115
116 } // namespace base
117
118 #endif // BASE_WORKER_POOL_JOB_H_
OLDNEW
« no previous file with comments | « base/i18n/file_util_icu.cc ('k') | base/worker_pool_job.cc » ('j') | base/worker_pool_job.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698