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

Side by Side Diff: chrome_frame/scoped_initialization_manager.h

Issue 12521002: Start and stop crash reporting outside of the loader lock. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: stop crash reporting when the module is no longer locked. Created 7 years, 9 months 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
« chrome_frame/chrome_tab.cc ('K') | « chrome_frame/chrome_tab.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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 CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_
6 #define CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_
7
8 #include "base/basictypes.h"
9 #include "base/lazy_instance.h"
10 #include "base/synchronization/lock.h"
11
12 namespace chrome_frame {
13
14 // A class intended to be instantiated on the stack in a dyanmically loaded
15 // shared object to initialize and shutdown the object's dependencies. |Traits|
16 // must be a type with two public static void(void) functions named Initialize
17 // and Shutdown. Traits::Initialize will be invoked when the first instance of
18 // this class is created and Traits::Shutdown will ordinarily be invoked when
19 // the last one is destroyed. Shutdown will be deferred if any instance's Commit
20 // method is invoked, causing whatever was initialized to outlive all instances
21 // of this class. Decommit can be invoked later to restore the original behavior
22 // (i.e., Shutdown will be invoked once all instances are destroyed).
robertshield 2013/03/12 03:16:49 Consider mentioning that multiple Commit() calls a
grt (UTC plus 2) 2013/03/12 14:45:51 Done.
23 template<class Traits>
24 class ScopedInitializationManager {
25 public:
26 ScopedInitializationManager() : manager_(manager_instance_.Get()) {
27 manager_.AddRef();
28 }
29 ~ScopedInitializationManager() {
30 manager_.Release();
31 }
32
33 // Causes crash reporting to outlive this and all other instances.
34 void Commit() {
35 manager_.Commit();
36 }
37
38 // Causes crash reporting to be stopped once this and all other instances have
39 // been destroyed.
40 void Decommit() {
41 manager_.Decommit();
42 }
43
44 private:
45 // The long-lived manager class. A single instance of this is lazily created
46 // when the first scoper is created and is never destroyed. Each scoper takes
47 // a reference on the manager. The initialize function is invoked when the
48 // first reference is taken. The Shutdown method is invoked when the last
49 // reference is released if Commit has not been invoked.
robertshield 2013/03/12 03:16:49 Nit: You could write this without the inner class,
grt (UTC plus 2) 2013/03/12 14:45:51 Hmm. The base::Lock would need to be lazy-initiali
robertshield 2013/03/12 16:06:12 Not overly complicated, just felt a little longer
50 class CrashReportingManager {
51 public:
52 CrashReportingManager() : ref_count_(0), committed_(false) {}
53 ~CrashReportingManager() {
54 // Instances of this class are leaked.
55 NOTREACHED();
56 }
57
58 void AddRef() {
59 base::AutoLock auto_lock(lock_);
60 DCHECK_LT(ref_count_, kuint32max);
61 if (++ref_count_ == 1 && !committed_)
robertshield 2013/03/12 03:16:49 nit: I mildly prefer to have the increment operati
grt (UTC plus 2) 2013/03/12 14:45:51 I disagree just enough to want to leave it this wa
robertshield 2013/03/12 16:06:12 I suspected you might :-)
62 Traits::Initialize();
63 }
64
65 void Release() {
66 base::AutoLock auto_lock(lock_);
67 DCHECK_GT(ref_count_, 0U);
68 if (--ref_count_ == 0 && !committed_)
69 Traits::Shutdown();
70 }
71
72 void Commit() {
73 base::AutoLock auto_lock(lock_);
74 DCHECK_NE(ref_count_, 0U);
75 committed_ = true;
76 }
77
78 void Decommit() {
79 base::AutoLock auto_lock(lock_);
80 DCHECK_NE(ref_count_, 0U);
81 committed_ = false;
82 }
83
84 base::Lock lock_;
85 uint32 ref_count_;
86 bool committed_;
87 DISALLOW_COPY_AND_ASSIGN(CrashReportingManager);
88 };
89
90 static typename base::LazyInstance<CrashReportingManager>::Leaky
91 manager_instance_;
92
93 CrashReportingManager& manager_;
94 DISALLOW_COPY_AND_ASSIGN(ScopedInitializationManager);
95 };
96
97 template<class Traits>
98 typename base::LazyInstance<
99 typename ScopedInitializationManager<Traits>::CrashReportingManager>::Leaky
100 ScopedInitializationManager<Traits>::manager_instance_ =
101 LAZY_INSTANCE_INITIALIZER;
102
103 } // namespace chrome_frame
104
105 #endif // CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_
OLDNEW
« chrome_frame/chrome_tab.cc ('K') | « chrome_frame/chrome_tab.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698