diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2011-09-22 16:54:50 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2011-09-23 11:28:31 +0100 |
commit | 2981787353f9862c076cf1c72484c4d5ea234999 (patch) | |
tree | a29d33b785f8a83d3aeb6cab5a344bd88b4ef004 | |
parent | 4695c8fe269d04eff269522dc6a0f67795a07dac (diff) |
Master: poison singleton pointer when disposed
Previously, when the 'default' instance of McdMaster (i.e., the
singleton) was disposed, the 'default_master' variable was left pointing
to it. This is basically fine in practice, since the McdMaster is meant
to survive for the lifetime of the connection. But I hit a weird crash
(caused by the test suite's version of MC waiting 5 seconds after the
McdMaster is destroyed before closing, which interacts badly with the
reconnection timeout being less than 5 seconds) and it would have been
much clearer what was happening if 'default_master' had held a known-bad
address rather than a possibly-valid pointer to a freed object.
This doesn't change the behaviour of the code in any significant way:
we'll still crash in this situation. But as far as I can tell the bug is
harmless.
-rw-r--r-- | src/mcd-master.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/mcd-master.c b/src/mcd-master.c index 29e9fbe8..9a468b0e 100644 --- a/src/mcd-master.c +++ b/src/mcd-master.c @@ -118,6 +118,10 @@ typedef struct { gpointer userdata; } McdAccountConnectionData; +/* Used to poison 'default_master' when the object it points to is disposed. + * The default_master should basically be alive for the duration of the MC run. + */ +#define POISONED_MASTER ((McdMaster *) 0xdeadbeef) static McdMaster *default_master = NULL; @@ -425,6 +429,11 @@ _mcd_master_dispose (GObject * object) priv->dispatcher = NULL; g_object_unref (priv->proxy); + if (default_master == (McdMaster *) object) + { + default_master = POISONED_MASTER; + } + G_OBJECT_CLASS (mcd_master_parent_class)->dispose (object); } @@ -549,6 +558,9 @@ mcd_master_get_default (void) { if (!default_master) default_master = MCD_MASTER (g_object_new (MCD_TYPE_MASTER, NULL)); + + g_return_val_if_fail (default_master != POISONED_MASTER, NULL); + return default_master; } |