From d0a096f2558dcb345286863b0bb03841127477c1 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 23 Sep 2014 15:32:16 -0700 Subject: [PATCH] Bug 1070340 (Part 1) - Add ShutdownTracker to imagelib. r=tn --- image/build/nsImageModule.cpp | 2 + image/src/ShutdownTracker.cpp | 76 +++++++++++++++++++++++++++++++++++ image/src/ShutdownTracker.h | 46 +++++++++++++++++++++ image/src/moz.build | 1 + 4 files changed, 125 insertions(+) create mode 100644 image/src/ShutdownTracker.cpp create mode 100644 image/src/ShutdownTracker.h diff --git a/image/build/nsImageModule.cpp b/image/build/nsImageModule.cpp index 779b34853d7..12e7fb44ea1 100644 --- a/image/build/nsImageModule.cpp +++ b/image/build/nsImageModule.cpp @@ -11,6 +11,7 @@ #include "ImageFactory.h" #include "RasterImage.h" +#include "ShutdownTracker.h" #include "SurfaceCache.h" #include "imgLoader.h" @@ -85,6 +86,7 @@ static bool sInitialized = false; nsresult mozilla::image::InitModule() { + mozilla::image::ShutdownTracker::Initialize(); mozilla::image::DiscardTracker::Initialize(); mozilla::image::ImageFactory::Initialize(); mozilla::image::RasterImage::Initialize(); diff --git a/image/src/ShutdownTracker.cpp b/image/src/ShutdownTracker.cpp new file mode 100644 index 00000000000..5957c98f911 --- /dev/null +++ b/image/src/ShutdownTracker.cpp @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ShutdownTracker.h" + +#include "mozilla/Services.h" +#include "nsAutoPtr.h" +#include "nsIObserver.h" +#include "nsIObserverService.h" + +namespace mozilla { +namespace image { + +class ShutdownTrackerImpl; + +/////////////////////////////////////////////////////////////////////////////// +// Static Data +/////////////////////////////////////////////////////////////////////////////// + +// Whether we've observed shutdown starting yet. +static bool sShutdownHasStarted = false; + + +/////////////////////////////////////////////////////////////////////////////// +// Implementation +/////////////////////////////////////////////////////////////////////////////// + +struct ShutdownObserver : public nsIObserver +{ + NS_DECL_ISUPPORTS + + NS_IMETHOD Observe(nsISupports*, const char* aTopic, const char16_t*) + { + if (strcmp(aTopic, "xpcom-shutdown") != 0) { + return NS_OK; + } + + nsCOMPtr os = services::GetObserverService(); + if (os) { + os->RemoveObserver(this, "xpcom-shutdown"); + } + + sShutdownHasStarted = true; + return NS_OK; + } + +private: + virtual ~ShutdownObserver() { } +}; + +NS_IMPL_ISUPPORTS(ShutdownObserver, nsIObserver) + + +/////////////////////////////////////////////////////////////////////////////// +// Public API +/////////////////////////////////////////////////////////////////////////////// + +/* static */ void +ShutdownTracker::Initialize() +{ + nsCOMPtr os = services::GetObserverService(); + if (os) { + os->AddObserver(new ShutdownObserver, "xpcom-shutdown", false); + } +} + +/* static */ bool +ShutdownTracker::ShutdownHasStarted() +{ + return sShutdownHasStarted; +} + +} // namespace image +} // namespace mozilla diff --git a/image/src/ShutdownTracker.h b/image/src/ShutdownTracker.h new file mode 100644 index 00000000000..e1287b6cfb3 --- /dev/null +++ b/image/src/ShutdownTracker.h @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * ShutdownTracker is an imagelib-global service that allows callers to check + * whether shutdown has started. + */ + +#ifndef MOZILLA_IMAGELIB_SHUTDOWNTRACKER_H_ +#define MOZILLA_IMAGELIB_SHUTDOWNTRACKER_H_ + +namespace mozilla { +namespace image { + +/** + * ShutdownTracker is an imagelib-global service that allows callers to check + * whether shutdown has started. It exists to avoid the need for registering many + * 'xpcom-shutdown' notification observers on short-lived objects, which would + * have an unnecessary performance cost. + */ +struct ShutdownTracker +{ + /** + * Initialize static data. Called during imagelib module initialization. + */ + static void Initialize(); + + /** + * Check whether shutdown has started. Callers can use this to check whether + * it's safe to access XPCOM services; if shutdown has started, such calls + * must be avoided. + * + * @return true if shutdown has already started. + */ + static bool ShutdownHasStarted(); + +private: + virtual ~ShutdownTracker() = 0; // Forbid instantiation. +}; + +} // namespace image +} // namespace mozilla + +#endif // MOZILLA_IMAGELIB_SHUTDOWNTRACKER_H_ diff --git a/image/src/moz.build b/image/src/moz.build index 1b3529fce03..1ea581711a7 100644 --- a/image/src/moz.build +++ b/image/src/moz.build @@ -32,6 +32,7 @@ UNIFIED_SOURCES += [ 'imgTools.cpp', 'OrientedImage.cpp', 'ScriptedNotificationObserver.cpp', + 'ShutdownTracker.cpp', 'SurfaceCache.cpp', 'SVGDocumentWrapper.cpp', 'VectorImage.cpp',