Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: src/plugin/Instances.h

Issue 29333107: Issue #1652, #3456 - Replace 's_asyncWebBrowser2' with thread-safe facilities
Left Patch Set: Created Dec. 29, 2015, 5:54 p.m.
Right Patch Set: rebase only Created July 27, 2016, 10:26 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/plugin/PluginClass.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #ifndef _INSTANCES_H_ 18 #ifndef _INSTANCES_H_
19 #define _INSTANCES_H_ 19 #define _INSTANCES_H_
20 20
21 #include <map>
21 #include <mutex> 22 #include <mutex>
22 #include <set> 23 #include <set>
23 24
24 /** 25 /**
26 * A base class for a synchronized map from threads to BHO instances.
27 *
28 * This is a base class for 'CurrentThreadMap', defined in PluginClass.cpp.
29 * It's separated out here for testability.
30 * This class should not be used as polymorphic base class, as it has no virtual base class.
31 *
32 * The member functions here not simply forwarded versions of the container func tions.
33 * Rather, they are specialized for tracking BHO calls to SetSite().
34 * Their semantics allow for verification that the call pattern is as expected.
35 *
36 * The key to the map (in the subclass) is the thread ID, thus operations are se rialized on a per-key basis.
37 * Calls to SetSite() bracket all other calls, so on a per-key basis
38 * the order of operations is always either (insert / find-success / erase) or (find-failure).
39 * The library guarantees for std::map seem to indicate that operations on diffe rent keys
40 * do not interfer with each other, but there's some ambiguity there.
41 * This class is synchronized as a matter of defensive programming.
42 */
43 template<class Key, class T, T nullValue>
44 class SyncMap
45 {
46 typedef std::lock_guard<std::mutex> SentryType;
47
48 /**
49 * Underlying map container
50 */
51 std::map<Key, T> idMap;
52
53 /**
54 * Synchronization primitive
55 */
56 mutable std::mutex mutex;
57
58 public:
59 /**
60 * Returns true if (as expected) no key of value 'id' was present.
61 * Returns false otherwise.
62 */
63 bool AddIfAbsent(Key id, T p)
64 {
65 SentryType sentry(mutex);
66 auto it = idMap.insert(std::make_pair(id, p));
67 return it.second;
68 // Assert it.second==true implies the insertion took place,
69 // which means there was no key of value 'id' already present.
70 }
71
72 /**
73 * Returns true if (as expected) a key of value 'id' was already present.
74 * Returns false otherwise.
75 */
76 bool RemoveIfPresent(Key id)
77 {
78 SentryType sentry(mutex);
79 auto it = idMap.find(id);
80 if (it == idMap.end())
81 {
82 return false;
83 }
84 idMap.erase(it);
85 return true;
86 }
87
88 /**
89 * Returns a non-nullValue if a key of value 'id' is present.
90 * Returns nullValue otherwise.
91 */
92 T Locate(Key id) const
93 {
94 SentryType sentry(mutex);
95 auto it = idMap.find(id);
96 return (it != idMap.end()) ? it->second : nullValue;
97 }
98 };
99
100 /**
25 * Template class for a synchronized set of BHO instances 101 * Template class for a synchronized set of BHO instances
sergei 2016/01/04 15:34:31 Do you mind to change the comment a bit? If it's
Eric 2016/01/04 17:49:20 I don't see a need, given what you've said so far.
sergei 2016/01/29 15:28:55 I disagree that the description of generic templat
Eric 2016/01/29 16:16:12 Your objection here is that you don't like the tem
Oleksandr 2016/02/01 18:03:13 I think Sergei was merely talking about the commen
Eric 2016/02/03 14:57:27 I don't believe so. He has said more that once tha
26 *
27 */ 102 */
28 template<class T, T nullValue> 103 template<class T, T nullValue>
29 class SyncSet 104 class SyncSet
30 { 105 {
31 typedef std::lock_guard<std::mutex> SentryType; 106 typedef std::lock_guard<std::mutex> SentryType;
32 107
33 /** 108 /**
34 * Underlying set container 109 * Underlying set container
35 */ 110 */
36 std::set<T> set; 111 std::set<T> set;
37 112
38 /** 113 /**
39 * Synchronization primitive 114 * Synchronization primitive
40 */ 115 */
41 std::mutex mutex; 116 mutable std::mutex mutex;
sergei 2016/01/04 15:34:31 I guess it should be `mutable` because it can be u
Eric 2016/01/04 17:49:20 Done. The only 'const' method, though, is 'Empty(
42 117
43 public: 118 public:
44 /** 119 /**
45 * \return 120 * \return
46 * true if (as expected) the argument was not already a member of the set 121 * true if (as expected) the argument was not already a member of the set
47 * false otherwise 122 * false otherwise
48 * 123 *
49 * \par Postcondition 124 * \par Postcondition
50 * - argument is a member of the set 125 * - argument is a member of the set
51 */ 126 */
52 bool InsertIfAbsent(T p) 127 bool InsertIfAbsent(T p)
sergei 2016/01/04 15:34:30 it would be better to have instead methods which a
Eric 2016/01/04 17:49:20 If this were generic library code, we'd want decla
sergei 2016/01/29 15:28:55 I disagree with that attitude. I think it should b
Eric 2016/01/29 16:16:12 You haven't identified a defect here. You have no
Oleksandr 2016/02/01 18:03:13 I don't have a strong opinion on this, but I agree
Eric 2016/02/03 14:57:27 Answered above.
53 { 128 {
54 SentryType sentry(mutex); 129 SentryType sentry(mutex);
55 auto it = set.find(p); 130 auto it = set.find(p);
56 if (it != set.end()) 131 if (it != set.end())
57 { 132 {
58 return false; 133 return false;
59 } 134 }
60 set.insert(p); 135 set.insert(p);
61 return true; 136 return true;
62 } 137 }
63 138
64 /** 139 /**
65 * \return 140 * \return
66 * true if (as expected) the argument was already a member of the set 141 * true if (as expected) the argument was already a member of the set
67 * false otherwise 142 * false otherwise
68 * 143 *
69 * \par Postcondition 144 * \par Postcondition
70 * - argument is not a member of the set 145 * - argument is not a member of the set
71 */ 146 */
72 bool EraseWithCheck(T p) 147 bool EraseWithCheck(T p)
sergei 2016/01/04 15:34:30 The argument should be `const T&`.
Eric 2016/01/04 17:49:20 See above. Pass by value is desirable.
73 { 148 {
74 SentryType sentry(mutex); 149 SentryType sentry(mutex);
75 auto it = set.find(p); 150 auto it = set.find(p);
76 if (it == set.end()) 151 if (it == set.end())
77 { 152 {
78 return false; 153 return false;
79 } 154 }
80 set.erase(it); 155 set.erase(it);
81 return true; 156 return true;
82 } 157 }
83 158
84 /** 159 /**
85 * \param f 160 * \param f
86 * Search criterion is a simple predicate function 161 * Search criterion is a simple predicate function
87 * 162 *
88 * \return 163 * \return
89 * - If no member of the set meets the search criterion, the null value 164 * - If no member of the set meets the search criterion, the null value
90 * - Otherwise some member of the set that meets the search criterion 165 * - Otherwise some member of the set that meets the search criterion
91 */ 166 */
92 T LinearSearch(std::function<bool(T)> f) 167 T LinearSearch(std::function<bool(T)> f)
sergei 2016/01/04 15:34:30 I would like to have a constant reference to T as
sergei 2016/01/04 15:34:30 Should it be a constant method?
sergei 2016/01/04 15:34:31 it would be also good to pass the predicate as a c
Eric 2016/01/04 17:49:20 It's only ever used with lambda functions, so an l
Eric 2016/01/04 17:49:20 No. If we wanted a second, 'const'-aware definiti
Eric 2016/01/04 17:49:20 We're passing 'T' by value everywhere.
sergei 2016/01/29 15:28:55 It's just a dirty code, isn't it clear?
sergei 2016/01/29 15:28:55 This method does not change the main sate of the c
Eric 2016/01/29 16:16:12 The whole discussion of 'const' declaration here h
93 { 168 {
94 SentryType sentry(mutex); 169 SentryType sentry(mutex);
95 for (auto it : set) 170 for (auto member : set)
sergei 2016/01/04 15:34:30 JIC, `it` does not refer to an iterator here, I wo
Eric 2016/01/04 17:49:20 OK.
96 { 171 {
97 bool b = f(it); 172 bool b = f(member);
98 if (b) 173 if (b)
99 { 174 {
100 return it; 175 return member;
101 } 176 }
102 } 177 }
103 return nullValue; 178 return nullValue;
104 } 179 }
105 180
106 bool Empty() const 181 bool Empty() const
107 { 182 {
183 SentryType sentry(mutex);
108 return set.empty(); 184 return set.empty();
sergei 2016/01/04 15:34:30 SentryType sentry(mutex); is missed here
Eric 2016/01/04 17:49:20 This function is only instantiated in the unit tes
109 } 185 }
110 }; 186 };
111 187
112 #endif 188 #endif
LEFTRIGHT

Powered by Google App Engine
This is Rietveld