Merge lp:~alan-griffiths/compiz-core/rework-updatePlugins into lp:compiz-core
- rework-updatePlugins
- Merge into 0.9.7
Status: | Merged |
---|---|
Merged at revision: | 3075 |
Proposed branch: | lp:~alan-griffiths/compiz-core/rework-updatePlugins |
Merge into: | lp:compiz-core |
Diff against target: |
686 lines (+439/-107) (has conflicts) 4 files modified
include/core/plugin.h (+1/-1) src/privatescreen.h (+6/-0) src/privatescreen/tests/test-privatescreen.cpp (+352/-13) src/screen.cpp (+80/-93) Text conflict in src/privatescreen/tests/test-privatescreen.cpp |
To merge this branch: | bzr merge lp:~alan-griffiths/compiz-core/rework-updatePlugins |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Approve | ||
Review via email: mp+99981@code.launchpad.net |
This proposal supersedes a proposal from 2012-03-28.
Commit message
Description of the change
Avoid graphics corruption and hangs on compiz start-up by ensuring that
plugins don't get initialized, de-initialized and re-initialzed during
start-up. (LP: #963093) (LP: #963633)
The multiple init/fini/init calls occured when compiz was asked to load an
invalid plugin name. This occurred most recently as plugins "bailer" and
"detection" were left in some peoples' configs while the plugins themselves
no longer exist in the current compiz release.
The source of the graphics corruption and hangs has been found to be a
problem in the composite and/or opengl plugins. One or both of them are unsafe
to init/fini multiple times without a full compiz restart. So the root cause
is not exactly known yet. However composite and opengl are not alone; many
plugins have bugs with init/fini/init sequences, so it is valuable to fix
the start-up plugin ordering as this does.
Essentially this fix works by remembering which plugins don't exist at all
and putting them on a black list. Then subsequent updates check the blacklist
and know they should never include those failed plugins in testing whether
the active plugin lists have changed.
The final part of the fix is to remove a rendundant call to updatePlugins from
EventManager::init. It is not required as main tells PluginManager when to
load plugins on startup.
IMPORTANT NOTE FOR UBUNTU PACKAGING
In downstream ubuntu branches the DEFAULT_PLUGINS list in "debian/rules" also causes multiple plugin loads on start-up and prevents this fix from working! The solution is to change DEFAULT_PLUGINS to just "ccp".
ORIGINAL DESCRIPTION:
Some test cases to cover what we need.
Combined Daniel's "blacklist" with some cleanup of the code and ignoring any non-existent plugins entirely.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I've tested it now. The big startup bugs are avoided, however it causes a regression: Disabling plugins in ccsm has no effect. Those plugins remain active and running even after they are removed from the active_plugins list. That's one reason why I proposed the new logging last night. It's useful :)
Arguably, it's an acceptable compromise to fix the critical issues and introduce a less severe bug. However the the size of the new code in updatePlugins still makes me a little scared. Also, I managed an equally successful hack yesterday with just a few lines changed, but similar regressions.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Replaced by: https:/
Which has no such regressions. And is smaller, simpler.
Daniel van Vugt (vanvugt) wrote : | # |
Manual testing in precise is all good. The bugs are fixed.
But...
1. Please don't change formatting unnecessarily from func (x) to func(x). I agree with the latter but it's not what compiz uses.
2. You alternative between both styles inconsistently: func (x) and func(x)
3. The critical bugs this branch fixes are not mentioned anywhere and we don't have a usable commit message. But I can add those.
Daniel van Vugt (vanvugt) wrote : | # |
Also, please try to avoid renaming variables (even though you're right) this late in a stable release cycle. It increases the sizes of diffs and makes critical bug fixes harder to review.
Daniel van Vugt (vanvugt) wrote : | # |
Updated the description and linked relevant bugs.
Daniel van Vugt (vanvugt) wrote : | # |
Also, repeatedly calling: desiredPlugins[
is inefficient and harder to read.
We should just do: const CompString &name = desiredPlugins[
and then use "name".
Daniel van Vugt (vanvugt) wrote : | # |
Damn. It did contain real conflicts, but I've fixed them.
- 3075. By Alan Griffiths
-
Avoid graphics corruption and hangs on compiz start-up by ensuring that
plugins don't get initialized, de-initialized and re-initialzed during
start-up. (LP: #963093) (LP: #963633)The multiple init/fini/init calls occured when compiz was asked to load an
invalid plugin name. This occurred most recently as plugins "bailer" and
"detection" were left in some peoples' configs while the plugins themselves
no longer exist in the current compiz release.The source of the graphics corruption and hangs has been found to be a
problem in the composite and/or opengl plugins. One or both of them are unsafe
to init/fini multiple times without a full compiz restart. So the root cause
is not exactly known yet. However composite and opengl are not alone; many
plugins have bugs with init/fini/init sequences, so it is valuable to fix
the start-up plugin ordering as this does.Essentially this fix works by remembering which plugins don't exist at all
and putting them on a black list. Then subsequent updates check the blacklist
and know they should never include those failed plugins in testing whether
the active plugin lists have changed.The final part of the fix is to remove a rendundant call to updatePlugins from
EventManager::init. It is not required as main tells PluginManager when to
load plugins on startup.IMPORTANT NOTE FOR UBUNTU PACKAGING
In downstream ubuntu branches the DEFAULT_PLUGINS list in "debian/rules" also
causes multiple plugin loads on start-up and prevents this fix from working!
The solution is to change DEFAULT_PLUGINS to just "ccp".
Preview Diff
1 | === modified file 'include/core/plugin.h' | |||
2 | --- include/core/plugin.h 2012-02-16 05:31:28 +0000 | |||
3 | +++ include/core/plugin.h 2012-03-29 17:16:19 +0000 | |||
4 | @@ -207,7 +207,7 @@ | |||
5 | 207 | * CompPlugin::pop()'d. | 207 | * CompPlugin::pop()'d. |
6 | 208 | */ | 208 | */ |
7 | 209 | static List & getPlugins (); | 209 | static List & getPlugins (); |
9 | 210 | 210 | ||
10 | 211 | /** | 211 | /** |
11 | 212 | * Gets a list of the names of all the known plugins, including plugins that may | 212 | * Gets a list of the names of all the known plugins, including plugins that may |
12 | 213 | * have already been loaded. | 213 | * have already been loaded. |
13 | 214 | 214 | ||
14 | === modified file 'src/privatescreen.h' | |||
15 | --- src/privatescreen.h 2012-03-24 09:49:30 +0000 | |||
16 | +++ src/privatescreen.h 2012-03-29 17:16:19 +0000 | |||
17 | @@ -45,6 +45,8 @@ | |||
18 | 45 | 45 | ||
19 | 46 | #include "core_options.h" | 46 | #include "core_options.h" |
20 | 47 | 47 | ||
21 | 48 | #include <set> | ||
22 | 49 | |||
23 | 48 | /** | 50 | /** |
24 | 49 | * A wrapping of the X display screen. This takes care of communication to the | 51 | * A wrapping of the X display screen. This takes care of communication to the |
25 | 50 | * X server. | 52 | * X server. |
26 | @@ -574,6 +576,10 @@ | |||
27 | 574 | private: | 576 | private: |
28 | 575 | CompOption::Value plugin; | 577 | CompOption::Value plugin; |
29 | 576 | bool dirtyPluginList; | 578 | bool dirtyPluginList; |
30 | 579 | typedef std::set<CompString> CompStringSet; | ||
31 | 580 | CompStringSet blacklist; | ||
32 | 581 | |||
33 | 582 | CompOption::Value::Vector mergedPluginList(); | ||
34 | 577 | }; | 583 | }; |
35 | 578 | 584 | ||
36 | 579 | class GrabList | 585 | class GrabList |
37 | 580 | 586 | ||
38 | === modified file 'src/privatescreen/tests/test-privatescreen.cpp' | |||
39 | --- src/privatescreen/tests/test-privatescreen.cpp 2012-03-29 13:33:39 +0000 | |||
40 | +++ src/privatescreen/tests/test-privatescreen.cpp 2012-03-29 17:16:19 +0000 | |||
41 | @@ -175,6 +175,29 @@ | |||
42 | 175 | MOCK_CONST_METHOD0(createFailed, bool ()); | 175 | MOCK_CONST_METHOD0(createFailed, bool ()); |
43 | 176 | }; | 176 | }; |
44 | 177 | 177 | ||
45 | 178 | class StubActivePluginsOption | ||
46 | 179 | { | ||
47 | 180 | public: | ||
48 | 181 | StubActivePluginsOption(CoreOptions& co) : co(co) | ||
49 | 182 | { | ||
50 | 183 | CompOption::Vector& mOptions = co.getOptions (); | ||
51 | 184 | CompOption::Value::Vector list; | ||
52 | 185 | CompOption::Value value; | ||
53 | 186 | |||
54 | 187 | // active_plugins | ||
55 | 188 | mOptions[CoreOptions::ActivePlugins].setName ("active_plugins", CompOption::TypeList); | ||
56 | 189 | list.clear (); | ||
57 | 190 | value.set(CompString ("core")); | ||
58 | 191 | list.push_back (value); | ||
59 | 192 | } | ||
60 | 193 | |||
61 | 194 | bool setActivePlugins(const char*, const char* key, CompOption::Value & value) | ||
62 | 195 | { | ||
63 | 196 | return co.setOption(key, value); | ||
64 | 197 | } | ||
65 | 198 | private: | ||
66 | 199 | CoreOptions& co; | ||
67 | 200 | }; | ||
68 | 178 | } // (anon) namespace | 201 | } // (anon) namespace |
69 | 179 | 202 | ||
70 | 180 | namespace { | 203 | namespace { |
71 | @@ -254,6 +277,17 @@ | |||
72 | 254 | } | 277 | } |
73 | 255 | return true; | 278 | return true; |
74 | 256 | } | 279 | } |
75 | 280 | |||
76 | 281 | CompStringList mockListPlugins (const char *path) | ||
77 | 282 | { | ||
78 | 283 | CompStringList list; | ||
79 | 284 | list.push_back("one"); | ||
80 | 285 | list.push_back("two"); | ||
81 | 286 | list.push_back("three"); | ||
82 | 287 | list.push_back("four"); | ||
83 | 288 | |||
84 | 289 | return list; | ||
85 | 290 | } | ||
86 | 257 | }; | 291 | }; |
87 | 258 | 292 | ||
88 | 259 | 293 | ||
89 | @@ -349,19 +383,320 @@ | |||
90 | 349 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | 383 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); |
91 | 350 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("two"))). | 384 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("two"))). |
92 | 351 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | 385 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); |
106 | 352 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). | 386 | <<<<<<< TREE |
107 | 353 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | 387 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). |
108 | 354 | 388 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | |
109 | 355 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); // Once for "three" which doesn't load | 389 | |
110 | 356 | 390 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); // Once for "three" which doesn't load | |
111 | 357 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | 391 | |
112 | 358 | WillOnce(Return(false)); | 392 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). |
113 | 359 | 393 | WillOnce(Return(false)); | |
114 | 360 | ps.updatePlugins(); | 394 | |
115 | 361 | 395 | ps.updatePlugins(); | |
116 | 362 | // TODO Some cleanup that probably ought to be automatic. | 396 | |
117 | 363 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(2); | 397 | // TODO Some cleanup that probably ought to be automatic. |
118 | 364 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | 398 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(2); |
119 | 399 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | ||
120 | 400 | ======= | ||
121 | 401 | EXPECT_CALL(mockfs.mockVtableTwo, init()).WillOnce(Return(true)); | ||
122 | 402 | |||
123 | 403 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). | ||
124 | 404 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
125 | 405 | EXPECT_CALL(mockfs.mockVtableThree, init()).WillOnce(Return(false)); | ||
126 | 406 | |||
127 | 407 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); // Once for "three" which doesn't load | ||
128 | 408 | |||
129 | 409 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
130 | 410 | WillOnce(Return(false)); | ||
131 | 411 | |||
132 | 412 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
133 | 413 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
134 | 414 | |||
135 | 415 | ps.updatePlugins(); | ||
136 | 416 | |||
137 | 417 | Mock::VerifyAndClearExpectations(&mockfs); | ||
138 | 418 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
139 | 419 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
140 | 420 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
141 | 421 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
142 | 422 | |||
143 | 423 | // TODO Some cleanup that probably ought to be automatic. | ||
144 | 424 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(2); | ||
145 | 425 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | ||
146 | 426 | EXPECT_CALL(mockfs.mockVtableOne, finiScreen(Ne((void*)0))).Times(1); | ||
147 | 427 | EXPECT_CALL(mockfs.mockVtableOne, fini()).Times(1); | ||
148 | 428 | EXPECT_CALL(mockfs.mockVtableTwo, finiScreen(Ne((void*)0))).Times(1); | ||
149 | 429 | EXPECT_CALL(mockfs.mockVtableTwo, fini()).Times(1); | ||
150 | 430 | |||
151 | 431 | for (CompPlugin* p; (p = CompPlugin::pop ()) != 0; CompPlugin::unload (p)); | ||
152 | 432 | } | ||
153 | 433 | |||
154 | 434 | TEST(privatescreen_PluginManagerTest, updating_when_failing_to_load_plugin_in_middle_of_list) | ||
155 | 435 | { | ||
156 | 436 | using namespace testing; | ||
157 | 437 | |||
158 | 438 | MockCompScreen comp_screen; | ||
159 | 439 | |||
160 | 440 | cps::PluginManager ps(&comp_screen); | ||
161 | 441 | StubActivePluginsOption sapo(ps); | ||
162 | 442 | |||
163 | 443 | CompOption::Value::Vector values; | ||
164 | 444 | values.push_back ("core"); | ||
165 | 445 | ps.setPlugins (values); | ||
166 | 446 | ps.setDirtyPluginList (); | ||
167 | 447 | |||
168 | 448 | std::list <CompString> plugins; | ||
169 | 449 | plugins.push_back ("one"); | ||
170 | 450 | plugins.push_back ("three"); | ||
171 | 451 | plugins.push_back ("four"); | ||
172 | 452 | initialPlugins = plugins; | ||
173 | 453 | |||
174 | 454 | MockPluginFilesystem mockfs; | ||
175 | 455 | |||
176 | 456 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("one"))). | ||
177 | 457 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
178 | 458 | EXPECT_CALL(mockfs.mockVtableOne, init()).WillOnce(Return(true)); | ||
179 | 459 | |||
180 | 460 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). | ||
181 | 461 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
182 | 462 | EXPECT_CALL(mockfs.mockVtableThree, init()).WillOnce(Return(false)); | ||
183 | 463 | |||
184 | 464 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("four"))). | ||
185 | 465 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
186 | 466 | EXPECT_CALL(mockfs.mockVtableFour, init()).Times(1).WillRepeatedly(Return(true)); | ||
187 | 467 | |||
188 | 468 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); // Once for "three" which doesn't load | ||
189 | 469 | |||
190 | 470 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
191 | 471 | WillOnce(Return(true)); | ||
192 | 472 | |||
193 | 473 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
194 | 474 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
195 | 475 | |||
196 | 476 | ps.updatePlugins(); | ||
197 | 477 | |||
198 | 478 | Mock::VerifyAndClearExpectations(&mockfs); | ||
199 | 479 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
200 | 480 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
201 | 481 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
202 | 482 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
203 | 483 | |||
204 | 484 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
205 | 485 | WillOnce(Invoke(&sapo, &StubActivePluginsOption::setActivePlugins)); | ||
206 | 486 | |||
207 | 487 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
208 | 488 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
209 | 489 | |||
210 | 490 | ps.updatePlugins(); | ||
211 | 491 | |||
212 | 492 | Mock::VerifyAndClearExpectations(&mockfs); | ||
213 | 493 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
214 | 494 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
215 | 495 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
216 | 496 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
217 | 497 | |||
218 | 498 | // TODO Some cleanup that probably ought to be automatic. | ||
219 | 499 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(2); | ||
220 | 500 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | ||
221 | 501 | EXPECT_CALL(mockfs.mockVtableOne, finiScreen(Ne((void*)0))).Times(1); | ||
222 | 502 | EXPECT_CALL(mockfs.mockVtableOne, fini()).Times(1); | ||
223 | 503 | EXPECT_CALL(mockfs.mockVtableFour, finiScreen(Ne((void*)0))).Times(1); | ||
224 | 504 | EXPECT_CALL(mockfs.mockVtableFour, fini()).Times(1); | ||
225 | 505 | for (CompPlugin* p; (p = CompPlugin::pop ()) != 0; CompPlugin::unload (p)); | ||
226 | 506 | } | ||
227 | 507 | |||
228 | 508 | TEST(privatescreen_PluginManagerTest, calling_updatePlugins_with_fewer_plugins) | ||
229 | 509 | { | ||
230 | 510 | using namespace testing; | ||
231 | 511 | |||
232 | 512 | MockCompScreen comp_screen; | ||
233 | 513 | |||
234 | 514 | cps::PluginManager ps(&comp_screen); | ||
235 | 515 | |||
236 | 516 | StubActivePluginsOption sapo(ps); | ||
237 | 517 | |||
238 | 518 | // Stuff that has to be done before calling updatePlugins() | ||
239 | 519 | initialPlugins = std::list <CompString>(); | ||
240 | 520 | CompOption::Value::Vector values; | ||
241 | 521 | values.push_back ("core"); | ||
242 | 522 | ps.setPlugins (values); | ||
243 | 523 | ps.setDirtyPluginList (); | ||
244 | 524 | |||
245 | 525 | { | ||
246 | 526 | CompOption::Value::Vector plugins; | ||
247 | 527 | plugins.push_back ("one"); | ||
248 | 528 | plugins.push_back ("two"); | ||
249 | 529 | plugins.push_back ("three"); | ||
250 | 530 | CompOption::Value v(plugins); | ||
251 | 531 | sapo.setActivePlugins("core", "active_plugins", v); | ||
252 | 532 | } | ||
253 | 533 | |||
254 | 534 | MockPluginFilesystem mockfs; | ||
255 | 535 | |||
256 | 536 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("one"))). | ||
257 | 537 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
258 | 538 | EXPECT_CALL(mockfs.mockVtableOne, init()).WillOnce(Return(true)); | ||
259 | 539 | |||
260 | 540 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("two"))). | ||
261 | 541 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
262 | 542 | EXPECT_CALL(mockfs.mockVtableTwo, init()).WillOnce(Return(true)); | ||
263 | 543 | |||
264 | 544 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). | ||
265 | 545 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
266 | 546 | EXPECT_CALL(mockfs.mockVtableThree, init()).WillOnce(Return(true)); | ||
267 | 547 | |||
268 | 548 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
269 | 549 | WillOnce(Invoke(&sapo, &StubActivePluginsOption::setActivePlugins)); | ||
270 | 550 | |||
271 | 551 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
272 | 552 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
273 | 553 | |||
274 | 554 | ps.updatePlugins(); | ||
275 | 555 | |||
276 | 556 | Mock::VerifyAndClearExpectations(&mockfs); | ||
277 | 557 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
278 | 558 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
279 | 559 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
280 | 560 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
281 | 561 | |||
282 | 562 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | ||
283 | 563 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); | ||
284 | 564 | EXPECT_CALL(mockfs.mockVtableTwo, finiScreen(Ne((void*)0))).Times(1); | ||
285 | 565 | EXPECT_CALL(mockfs.mockVtableTwo, fini()).Times(1); | ||
286 | 566 | EXPECT_CALL(mockfs.mockVtableThree, fini()).Times(1); | ||
287 | 567 | EXPECT_CALL(mockfs.mockVtableThree, finiScreen(Ne((void*)0))).Times(1); | ||
288 | 568 | EXPECT_CALL(mockfs.mockVtableThree, init()).WillOnce(Return(true)); | ||
289 | 569 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
290 | 570 | WillOnce(Invoke(&sapo, &StubActivePluginsOption::setActivePlugins)); | ||
291 | 571 | |||
292 | 572 | { | ||
293 | 573 | CompOption::Value::Vector plugins; | ||
294 | 574 | plugins.push_back ("one"); | ||
295 | 575 | plugins.push_back ("three"); | ||
296 | 576 | CompOption::Value v(plugins); | ||
297 | 577 | sapo.setActivePlugins("core", "active_plugins", v); | ||
298 | 578 | } | ||
299 | 579 | |||
300 | 580 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
301 | 581 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
302 | 582 | |||
303 | 583 | ps.updatePlugins(); | ||
304 | 584 | |||
305 | 585 | Mock::VerifyAndClearExpectations(&mockfs); | ||
306 | 586 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
307 | 587 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
308 | 588 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
309 | 589 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
310 | 590 | |||
311 | 591 | // TODO Some cleanup that probably ought to be automatic. | ||
312 | 592 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(2); | ||
313 | 593 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(2); | ||
314 | 594 | EXPECT_CALL(mockfs.mockVtableOne, finiScreen(Ne((void*)0))).Times(1); | ||
315 | 595 | EXPECT_CALL(mockfs.mockVtableOne, fini()).Times(1); | ||
316 | 596 | EXPECT_CALL(mockfs.mockVtableThree, finiScreen(Ne((void*)0))).Times(1); | ||
317 | 597 | EXPECT_CALL(mockfs.mockVtableThree, fini()).Times(1); | ||
318 | 598 | |||
319 | 599 | for (CompPlugin* p; (p = CompPlugin::pop ()) != 0; CompPlugin::unload (p)); | ||
320 | 600 | } | ||
321 | 601 | |||
322 | 602 | TEST(privatescreen_PluginManagerTest, calling_updatePlugins_with_additional_plugins) | ||
323 | 603 | { | ||
324 | 604 | using namespace testing; | ||
325 | 605 | |||
326 | 606 | MockCompScreen comp_screen; | ||
327 | 607 | |||
328 | 608 | cps::PluginManager ps(&comp_screen); | ||
329 | 609 | |||
330 | 610 | StubActivePluginsOption sapo(ps); | ||
331 | 611 | |||
332 | 612 | // Stuff that has to be done before calling updatePlugins() | ||
333 | 613 | initialPlugins = std::list <CompString>(); | ||
334 | 614 | CompOption::Value::Vector values; | ||
335 | 615 | values.push_back ("core"); | ||
336 | 616 | ps.setPlugins (values); | ||
337 | 617 | ps.setDirtyPluginList (); | ||
338 | 618 | |||
339 | 619 | { | ||
340 | 620 | CompOption::Value::Vector plugins; | ||
341 | 621 | plugins.push_back ("one"); | ||
342 | 622 | plugins.push_back ("two"); | ||
343 | 623 | plugins.push_back ("four"); | ||
344 | 624 | CompOption::Value v(plugins); | ||
345 | 625 | sapo.setActivePlugins("core", "active_plugins", v); | ||
346 | 626 | } | ||
347 | 627 | |||
348 | 628 | MockPluginFilesystem mockfs; | ||
349 | 629 | |||
350 | 630 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("one"))). | ||
351 | 631 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
352 | 632 | EXPECT_CALL(mockfs.mockVtableOne, init()).WillOnce(Return(true)); | ||
353 | 633 | |||
354 | 634 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("two"))). | ||
355 | 635 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
356 | 636 | EXPECT_CALL(mockfs.mockVtableTwo, init()).WillOnce(Return(true)); | ||
357 | 637 | |||
358 | 638 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("four"))). | ||
359 | 639 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
360 | 640 | EXPECT_CALL(mockfs.mockVtableFour, init()).WillOnce(Return(true)); | ||
361 | 641 | |||
362 | 642 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
363 | 643 | WillOnce(Invoke(&sapo, &StubActivePluginsOption::setActivePlugins)); | ||
364 | 644 | |||
365 | 645 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
366 | 646 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
367 | 647 | |||
368 | 648 | ps.updatePlugins(); | ||
369 | 649 | |||
370 | 650 | Mock::VerifyAndClearExpectations(&mockfs); | ||
371 | 651 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
372 | 652 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
373 | 653 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
374 | 654 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
375 | 655 | |||
376 | 656 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(1); | ||
377 | 657 | EXPECT_CALL(mockfs.mockVtableFour, fini()).Times(1); | ||
378 | 658 | EXPECT_CALL(mockfs.mockVtableFour, finiScreen(Ne((void*)0))).Times(1); | ||
379 | 659 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("three"))). | ||
380 | 660 | WillOnce(Invoke(&mockfs, &MockPluginFilesystem::DummyLoader)); | ||
381 | 661 | EXPECT_CALL(mockfs.mockVtableThree, init()).WillOnce(Return(true)); | ||
382 | 662 | EXPECT_CALL(mockfs.mockVtableFour, init()).WillOnce(Return(true)); | ||
383 | 663 | EXPECT_CALL(comp_screen, _setOptionForPlugin(StrEq("core"), StrEq("active_plugins"), _)). | ||
384 | 664 | WillOnce(Invoke(&sapo, &StubActivePluginsOption::setActivePlugins)); | ||
385 | 665 | |||
386 | 666 | { | ||
387 | 667 | CompOption::Value::Vector plugins; | ||
388 | 668 | plugins.push_back ("one"); | ||
389 | 669 | plugins.push_back ("two"); | ||
390 | 670 | plugins.push_back ("three"); | ||
391 | 671 | plugins.push_back ("four"); | ||
392 | 672 | CompOption::Value v(plugins); | ||
393 | 673 | sapo.setActivePlugins("core", "active_plugins", v); | ||
394 | 674 | } | ||
395 | 675 | |||
396 | 676 | EXPECT_CALL(mockfs, ListPlugins(_)). | ||
397 | 677 | WillRepeatedly(Invoke(&mockfs, &MockPluginFilesystem::mockListPlugins)); | ||
398 | 678 | |||
399 | 679 | ps.updatePlugins(); | ||
400 | 680 | |||
401 | 681 | Mock::VerifyAndClearExpectations(&mockfs); | ||
402 | 682 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableOne); | ||
403 | 683 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableTwo); | ||
404 | 684 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableThree); | ||
405 | 685 | Mock::VerifyAndClearExpectations(&mockfs.mockVtableFour); | ||
406 | 686 | |||
407 | 687 | // TODO Some cleanup that probably ought to be automatic. | ||
408 | 688 | EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(4); | ||
409 | 689 | EXPECT_CALL(comp_screen, _finiPluginForScreen(Ne((void*)0))).Times(4); | ||
410 | 690 | EXPECT_CALL(mockfs.mockVtableFour, finiScreen(Ne((void*)0))).Times(1); | ||
411 | 691 | EXPECT_CALL(mockfs.mockVtableFour, fini()).Times(1); | ||
412 | 692 | EXPECT_CALL(mockfs.mockVtableThree, finiScreen(Ne((void*)0))).Times(1); | ||
413 | 693 | EXPECT_CALL(mockfs.mockVtableThree, fini()).Times(1); | ||
414 | 694 | EXPECT_CALL(mockfs.mockVtableTwo, finiScreen(Ne((void*)0))).Times(1); | ||
415 | 695 | EXPECT_CALL(mockfs.mockVtableTwo, fini()).Times(1); | ||
416 | 696 | EXPECT_CALL(mockfs.mockVtableOne, finiScreen(Ne((void*)0))).Times(1); | ||
417 | 697 | EXPECT_CALL(mockfs.mockVtableOne, fini()).Times(1); | ||
418 | 698 | |||
419 | 699 | >>>>>>> MERGE-SOURCE | ||
420 | 365 | for (CompPlugin* p; (p = CompPlugin::pop ()) != 0; CompPlugin::unload (p)); | 700 | for (CompPlugin* p; (p = CompPlugin::pop ()) != 0; CompPlugin::unload (p)); |
421 | 366 | } | 701 | } |
422 | 367 | 702 | ||
423 | @@ -398,5 +733,9 @@ | |||
424 | 398 | comp_screen.priv.reset(new PrivateScreen(&comp_screen)); | 733 | comp_screen.priv.reset(new PrivateScreen(&comp_screen)); |
425 | 399 | cps::EventManager& em(*comp_screen.priv.get()); | 734 | cps::EventManager& em(*comp_screen.priv.get()); |
426 | 400 | 735 | ||
427 | 736 | <<<<<<< TREE | ||
428 | 737 | ======= | ||
429 | 738 | em.setPlugins (values); | ||
430 | 739 | >>>>>>> MERGE-SOURCE | ||
431 | 401 | em.init(0); | 740 | em.init(0); |
432 | 402 | } | 741 | } |
433 | 403 | 742 | ||
434 | === modified file 'src/screen.cpp' | |||
435 | --- src/screen.cpp 2012-03-24 09:49:30 +0000 | |||
436 | +++ src/screen.cpp 2012-03-29 17:16:19 +0000 | |||
437 | @@ -893,83 +893,45 @@ | |||
438 | 893 | } | 893 | } |
439 | 894 | } | 894 | } |
440 | 895 | 895 | ||
443 | 896 | void | 896 | CompOption::Value::Vector |
444 | 897 | cps::PluginManager::updatePlugins () | 897 | cps::PluginManager::mergedPluginList () |
445 | 898 | { | 898 | { |
496 | 899 | unsigned int pListCount = 1; | 899 | std::list<CompString> availablePlugins(CompPlugin::availablePlugins ()); |
497 | 900 | 900 | ||
498 | 901 | possibleTap = NULL; | 901 | CompOption::Value::Vector result; |
499 | 902 | dirtyPluginList = false; | 902 | |
500 | 903 | 903 | CompOption::Value::Vector const& extraPluginsRequested = optionGetActivePlugins(); | |
451 | 904 | CompOption::Value::Vector &list = optionGetActivePlugins (); | ||
452 | 905 | |||
453 | 906 | /* Determine the number of plugins, which is core + | ||
454 | 907 | * initial plugins + plugins in option list in addition | ||
455 | 908 | * to initial plugins */ | ||
456 | 909 | foreach (CompString &pn, initialPlugins) | ||
457 | 910 | { | ||
458 | 911 | if (pn != "core") | ||
459 | 912 | pListCount++; | ||
460 | 913 | } | ||
461 | 914 | |||
462 | 915 | CompString lpName; | ||
463 | 916 | |||
464 | 917 | foreach (CompOption::Value &lp, list) | ||
465 | 918 | { | ||
466 | 919 | bool skip = false; | ||
467 | 920 | |||
468 | 921 | lpName = lp.s(); | ||
469 | 922 | |||
470 | 923 | if (lpName == "core") | ||
471 | 924 | continue; | ||
472 | 925 | |||
473 | 926 | foreach (CompString &p, initialPlugins) | ||
474 | 927 | { | ||
475 | 928 | if (p == lpName) | ||
476 | 929 | { | ||
477 | 930 | skip = true; | ||
478 | 931 | break; | ||
479 | 932 | } | ||
480 | 933 | } | ||
481 | 934 | |||
482 | 935 | /* plugin not in initial list */ | ||
483 | 936 | if (!skip) | ||
484 | 937 | pListCount++; | ||
485 | 938 | } | ||
486 | 939 | |||
487 | 940 | /* pListCount is now the number of plugisn contained in both the | ||
488 | 941 | * initial and new plugins list */ | ||
489 | 942 | CompOption::Value::Vector pList(pListCount); | ||
490 | 943 | |||
491 | 944 | if (pList.empty ()) | ||
492 | 945 | { | ||
493 | 946 | screen->setOptionForPlugin ("core", "active_plugins", plugin); | ||
494 | 947 | return; | ||
495 | 948 | } | ||
501 | 949 | 904 | ||
502 | 950 | /* Must have core as first plugin */ | 905 | /* Must have core as first plugin */ |
505 | 951 | pList.at (0) = "core"; | 906 | result.push_back("core"); |
504 | 952 | unsigned int j = 1; | ||
506 | 953 | 907 | ||
507 | 954 | /* Add initial plugins */ | 908 | /* Add initial plugins */ |
509 | 955 | foreach (CompString &p, initialPlugins) | 909 | foreach(CompString & p, initialPlugins) |
510 | 956 | { | 910 | { |
511 | 957 | if (p == "core") | 911 | if (p == "core") |
512 | 958 | continue; | 912 | continue; |
515 | 959 | pList.at (j).set (p); | 913 | |
516 | 960 | j++; | 914 | if (blacklist.find (p) != blacklist.end ()) |
517 | 915 | continue; | ||
518 | 916 | |||
519 | 917 | if (availablePlugins.end() != std::find(availablePlugins.begin(), availablePlugins.end(), p)) | ||
520 | 918 | result.push_back(p); | ||
521 | 961 | } | 919 | } |
522 | 962 | 920 | ||
523 | 963 | /* Add plugins not in the initial list */ | 921 | /* Add plugins not in the initial list */ |
525 | 964 | foreach (CompOption::Value &opt, list) | 922 | foreach(CompOption::Value const& opt, extraPluginsRequested) |
526 | 965 | { | 923 | { |
534 | 966 | std::list <CompString>::iterator it = initialPlugins.begin (); | 924 | if (opt.s() == "core") |
535 | 967 | bool skip = false; | 925 | continue; |
536 | 968 | 926 | ||
537 | 969 | if (opt.s () == "core") | 927 | if (blacklist.find (opt.s()) != blacklist.end ()) |
538 | 970 | continue; | 928 | continue; |
539 | 971 | 929 | ||
540 | 972 | for (; it != initialPlugins.end (); it++) | 930 | typedef std::list<CompString>::iterator iterator; |
541 | 931 | bool skip = false; | ||
542 | 932 | |||
543 | 933 | for (iterator it = initialPlugins.begin(); it != initialPlugins.end(); | ||
544 | 934 | it++) | ||
545 | 973 | { | 935 | { |
546 | 974 | if ((*it) == opt.s()) | 936 | if ((*it) == opt.s()) |
547 | 975 | { | 937 | { |
548 | @@ -980,50 +942,71 @@ | |||
549 | 980 | 942 | ||
550 | 981 | if (!skip) | 943 | if (!skip) |
551 | 982 | { | 944 | { |
553 | 983 | pList.at (j++).set (opt.s ()); | 945 | if (availablePlugins.end() != std::find(availablePlugins.begin(), availablePlugins.end(), opt.s())) |
554 | 946 | result.push_back(opt.s()); | ||
555 | 984 | } | 947 | } |
556 | 985 | } | 948 | } |
563 | 986 | 949 | return result; | |
564 | 987 | assert (j == pList.size ()); | 950 | } |
565 | 988 | 951 | ||
566 | 989 | /* j is initialized to 1 to make sure we never pop the core plugin */ | 952 | |
567 | 990 | unsigned int i; | 953 | void |
568 | 991 | for (i = j = 1; j < plugin.list ().size () && i < pList.size (); i++, j++) | 954 | cps::PluginManager::updatePlugins () |
569 | 955 | { | ||
570 | 956 | possibleTap = NULL; | ||
571 | 957 | dirtyPluginList = false; | ||
572 | 958 | |||
573 | 959 | CompOption::Value::Vector const desiredPlugins(mergedPluginList()); | ||
574 | 960 | |||
575 | 961 | unsigned int pluginIndex; | ||
576 | 962 | for (pluginIndex = 1; | ||
577 | 963 | pluginIndex < plugin.list ().size () && pluginIndex < desiredPlugins.size (); | ||
578 | 964 | pluginIndex++) | ||
579 | 992 | { | 965 | { |
581 | 993 | if (plugin.list ().at (j).s () != pList.at (i).s ()) | 966 | if (plugin.list ().at (pluginIndex).s () != desiredPlugins.at (pluginIndex).s ()) |
582 | 994 | break; | 967 | break; |
583 | 995 | } | 968 | } |
584 | 996 | 969 | ||
586 | 997 | CompPlugin::List pop; | 970 | unsigned int desireIndex = pluginIndex; |
587 | 998 | 971 | ||
589 | 999 | if (unsigned int const nPop = plugin.list ().size () - j) | 972 | // We have pluginIndex pointing at first difference (or end). |
590 | 973 | // Now pop plugins off stack to this point, but keep track that they are loaded | ||
591 | 974 | CompPlugin::List alreadyLoaded; | ||
592 | 975 | if (const unsigned int nPop = plugin.list().size() - pluginIndex) | ||
593 | 1000 | { | 976 | { |
595 | 1001 | for (j = 0; j < nPop; j++) | 977 | for (pluginIndex = 0; pluginIndex < nPop; pluginIndex++) |
596 | 1002 | { | 978 | { |
599 | 1003 | pop.push_back (CompPlugin::pop ()); | 979 | alreadyLoaded.push_back(CompPlugin::pop()); |
600 | 1004 | plugin.list ().pop_back (); | 980 | plugin.list().pop_back(); |
601 | 1005 | } | 981 | } |
602 | 1006 | } | 982 | } |
603 | 1007 | 983 | ||
605 | 1008 | for (; i < pList.size (); i++) | 984 | // Now work forward through requested plugins |
606 | 985 | for (; desireIndex < desiredPlugins.size(); desireIndex++) | ||
607 | 1009 | { | 986 | { |
608 | 1010 | CompPlugin *p = NULL; | 987 | CompPlugin *p = NULL; |
609 | 1011 | bool failedPush = false; | 988 | bool failedPush = false; |
610 | 1012 | 989 | ||
612 | 1013 | foreach (CompPlugin *pp, pop) | 990 | // If already loaded, just try to push it... |
613 | 991 | foreach(CompPlugin * pp, alreadyLoaded) | ||
614 | 1014 | { | 992 | { |
616 | 1015 | if (pList[i]. s () == pp->vTable->name ()) | 993 | if (desiredPlugins[desireIndex].s() == pp->vTable->name()) |
617 | 1016 | { | 994 | { |
618 | 1017 | if (CompPlugin::push (pp)) | 995 | if (CompPlugin::push (pp)) |
619 | 1018 | { | 996 | { |
620 | 1019 | p = pp; | 997 | p = pp; |
622 | 1020 | pop.erase (std::find (pop.begin (), pop.end (), pp)); | 998 | alreadyLoaded.erase( |
623 | 999 | std::find(alreadyLoaded.begin(), | ||
624 | 1000 | alreadyLoaded.end(), pp)); | ||
625 | 1021 | break; | 1001 | break; |
626 | 1022 | } | 1002 | } |
627 | 1023 | else | 1003 | else |
628 | 1024 | { | 1004 | { |
631 | 1025 | pop.erase (std::find (pop.begin (), pop.end (), pp)); | 1005 | alreadyLoaded.erase( |
632 | 1026 | CompPlugin::unload (pp); | 1006 | std::find(alreadyLoaded.begin(), |
633 | 1007 | alreadyLoaded.end(), pp)); | ||
634 | 1008 | blacklist.insert (desiredPlugins[desireIndex].s ()); | ||
635 | 1009 | CompPlugin::unload(pp); | ||
636 | 1027 | p = NULL; | 1010 | p = NULL; |
637 | 1028 | failedPush = true; | 1011 | failedPush = true; |
638 | 1029 | break; | 1012 | break; |
639 | @@ -1031,25 +1014,32 @@ | |||
640 | 1031 | } | 1014 | } |
641 | 1032 | } | 1015 | } |
642 | 1033 | 1016 | ||
643 | 1017 | // ...otherwise, try to load and push | ||
644 | 1034 | if (p == 0 && !failedPush) | 1018 | if (p == 0 && !failedPush) |
645 | 1035 | { | 1019 | { |
648 | 1036 | p = CompPlugin::load (pList[i].s ().c_str ()); | 1020 | p = CompPlugin::load(desiredPlugins[desireIndex].s ().c_str ()); |
649 | 1037 | 1021 | ||
650 | 1038 | if (p) | 1022 | if (p) |
651 | 1039 | { | 1023 | { |
653 | 1040 | if (!CompPlugin::push (p)) | 1024 | if (!CompPlugin::push(p)) |
654 | 1041 | { | 1025 | { |
656 | 1042 | CompPlugin::unload (p); | 1026 | blacklist.insert (desiredPlugins[desireIndex].s ()); |
657 | 1027 | CompPlugin::unload(p); | ||
658 | 1043 | p = 0; | 1028 | p = 0; |
659 | 1044 | } | 1029 | } |
660 | 1045 | } | 1030 | } |
661 | 1031 | else | ||
662 | 1032 | { | ||
663 | 1033 | blacklist.insert (desiredPlugins[desireIndex].s ()); | ||
664 | 1034 | } | ||
665 | 1046 | } | 1035 | } |
666 | 1047 | 1036 | ||
667 | 1048 | if (p) | 1037 | if (p) |
669 | 1049 | plugin.list ().push_back (p->vTable->name ()); | 1038 | plugin.list().push_back(p->vTable->name()); |
670 | 1050 | } | 1039 | } |
671 | 1051 | 1040 | ||
673 | 1052 | foreach (CompPlugin *pp, pop) | 1041 | // Any plugins that are loaded, but were not re-initialized can be unloaded. |
674 | 1042 | foreach(CompPlugin * pp, alreadyLoaded) | ||
675 | 1053 | CompPlugin::unload (pp); | 1043 | CompPlugin::unload (pp); |
676 | 1054 | 1044 | ||
677 | 1055 | if (!dirtyPluginList) | 1045 | if (!dirtyPluginList) |
678 | @@ -4626,9 +4616,6 @@ | |||
679 | 4626 | 4616 | ||
680 | 4627 | optionSetToggleWindowShadedKeyInitiate (CompScreenImpl::shadeWin); | 4617 | optionSetToggleWindowShadedKeyInitiate (CompScreenImpl::shadeWin); |
681 | 4628 | 4618 | ||
682 | 4629 | if (isDirtyPluginList ()) | ||
683 | 4630 | updatePlugins (); | ||
684 | 4631 | |||
685 | 4632 | return true; | 4619 | return true; |
686 | 4633 | } | 4620 | } |
687 | 4634 | 4621 |
Re: "Just because some plugins are "popped" to insert a new one, doesn't require them to be finalized."
This is untrue. Some plugins have loose dependencies on others and change their behaviour/features depending on what other plugins are loaded. Hence popped plugins must be fini'd and reinitialized.
Also, even if this branch works perfectly I would still be unhappy with the risk associated with such a large change in critical logic. Please don't hate me...
I'm looking at a much smaller/simpler solution. In fact I was designing it in my head as you designed this code. Will let you know if/when I think I have something that works.
In other news, the two critical bugs we're aiming to fix have had ZERO duplicates in the past two days. It sounds like the workarounds are working.