Merge lp:~alan-griffiths/compiz-core/init-sequence-fix into lp:compiz-core/0.9.5

Proposed by Alan Griffiths
Status: Merged
Approved by: Sam Spilsbury
Approved revision: 2976
Merged at revision: 2978
Proposed branch: lp:~alan-griffiths/compiz-core/init-sequence-fix
Merge into: lp:compiz-core/0.9.5
Diff against target: 60 lines (+5/-6)
2 files modified
src/screen.cpp (+1/-2)
xslt/bcop.xslt (+4/-4)
To merge this branch: bzr merge lp:~alan-griffiths/compiz-core/init-sequence-fix
Reviewer Review Type Date Requested Status
Compiz Maintainers Pending
Review via email: mp+91039@code.launchpad.net

Description of the change

CompManager::init() creates a CompScreen object (and will, after construction, store it's address in ::screen).
In the constructor of CompScreen a PrivateScreen object is constructed. This has a base subobject of type CoreOptions.
The constructor of CoreOptions NO LONGER dereferences the ::screen variable (to call CompScreen::addAction).
Calling a member function via an invalid (0 in this case) pointer was "undefined behaviour".

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

29 - <xsl:text> screen->addAction (&amp;</xsl:text>
30 + <xsl:text> if (screen) screen->addAction (&amp;</xsl:text>
31 <xsl:text>mOptions[</xsl:text>

Hrmm. Not sure if I like the idea of doing nul checks just to handle the startup case in CoreOptions.

To be honest, the option code shouldn't really be initialized until a plugin which is in charge of doing all the settings is loaded (eg, ccp). I would say it might be more appropriate here to allow *Options classes to have a default parameter in their constructor which indicates that they would rather have the options code initialized lazily, eg, in the bcop generated files, have a static bool initialized = false; variable and then atomically initialize the options whenever they are first written to, accessed or an action is bound.

That gains us a bit of startup time too, if we do it like that. Not really sure what the cost of having a once-only section optionGet* is, though I'm pretty sure there are compiler hints to deal with that no ?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Sam, I didn't want to change the runtime behaviour in the way you suggest.

The result is a workaround true, but the prior workaround was to test a flag inside the addAction member function (which was already in "undefined behaviour" land).

There are several issues that could be addressed in a larger fix:

1. I'd prefer to avoid the need for tests by ensuring the initialisation happens in a sane sequence (i.e. "screen" is intialised before CoreOptions is constructed).

2. I don't like having the global "screen" variable at all - objects that need a pointer to the CompScreen object should have it supplied on construction.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> Sam, I didn't want to change the runtime behaviour in the way you suggest.
>
> The result is a workaround true, but the prior workaround was to test a flag
> inside the addAction member function (which was already in "undefined
> behaviour" land).

So on the count of "its undefined behaviour", I'd be happy to merge this anyways.

>
> There are several issues that could be addressed in a larger fix:
>
> 1. I'd prefer to avoid the need for tests by ensuring the initialisation
> happens in a sane sequence (i.e. "screen" is intialised before CoreOptions is
> constructed).
>
> 2. I don't like having the global "screen" variable at all - objects that need
> a pointer to the CompScreen object should have it supplied on construction.

This is probably a lot more feasible than it looks - all plugins are already passed a CompScreen on construction (DI), it is trivial for them to use that. As for the other objects - all windows can store a pointer to the CompScreen object and then the other stuff is also easy, although we really, for things like actions we should just be passing them interfaces for ActionStorage or whatever and the implementation is CompScreen (for now).

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> > 2. I don't like having the global "screen" variable at all - objects that
> need
> > a pointer to the CompScreen object should have it supplied on construction.
>
> This is probably a lot more feasible than it looks - all plugins are already
> passed a CompScreen on construction (DI), it is trivial for them to use that.
> As for the other objects - all windows can store a pointer to the CompScreen
> object and then the other stuff is also easy, although we really, for things
> like actions we should just be passing them interfaces for ActionStorage or
> whatever and the implementation is CompScreen (for now).

Yeah, I'll get to that in a later fix.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/screen.cpp'
2--- src/screen.cpp 2012-01-29 16:28:45 +0000
3+++ src/screen.cpp 2012-02-01 10:20:28 +0000
4@@ -3196,7 +3196,7 @@
5 bool
6 CompScreen::addAction (CompAction *action)
7 {
8- if (!screenInitalized || !priv->initialized)
9+ if (!priv->initialized)
10 return false;
11
12 if (action->active ())
13@@ -4333,7 +4333,6 @@
14 CompPlugin *corePlugin;
15
16 priv = new PrivateScreen (this);
17- assert (priv);
18
19 screenInitalized = true;
20
21
22=== modified file 'xslt/bcop.xslt'
23--- xslt/bcop.xslt 2012-01-24 08:24:18 +0000
24+++ xslt/bcop.xslt 2012-02-01 10:20:28 +0000
25@@ -1272,7 +1272,7 @@
26 </xsl:with-param>
27 </xsl:call-template>
28 <xsl:if test="not (./passive_grab/text() = 'false')">
29- <xsl:text> screen->addAction (&amp;</xsl:text>
30+ <xsl:text> if (screen) screen->addAction (&amp;</xsl:text>
31 <xsl:text>mOptions[</xsl:text>
32 <xsl:call-template name="printOptionsEnumName"/>
33 <xsl:text>].value ().action ());
34@@ -1288,7 +1288,7 @@
35 </xsl:with-param>
36 </xsl:call-template>
37 <xsl:if test="not (./passive_grab/text() = 'false')">
38- <xsl:text> screen->addAction (&amp;</xsl:text>
39+ <xsl:text> if (screen) screen->addAction (&amp;</xsl:text>
40 <xsl:text>mOptions[</xsl:text>
41 <xsl:call-template name="printOptionsEnumName"/>
42 <xsl:text>].value ().action ());
43@@ -1304,7 +1304,7 @@
44 </xsl:with-param>
45 </xsl:call-template>
46 <xsl:if test="not (./passive_grab/text() = 'false')">
47- <xsl:text> screen->addAction (&amp;</xsl:text>
48+ <xsl:text> if (screen) screen->addAction (&amp;</xsl:text>
49 <xsl:text>mOptions[</xsl:text>
50 <xsl:call-template name="printOptionsEnumName"/>
51 <xsl:text>].value ().action ());
52@@ -1320,7 +1320,7 @@
53 </xsl:with-param>
54 </xsl:call-template>
55 <xsl:if test="not (./passive_grab/text() = 'false')">
56- <xsl:text> screen->addAction (&amp;</xsl:text>
57+ <xsl:text> if (screen) screen->addAction (&amp;</xsl:text>
58 <xsl:text>mOptions[</xsl:text>
59 <xsl:call-template name="printOptionsEnumName"/>
60 <xsl:text>].value ().action ());

Subscribers

People subscribed via source and target branches