--- a/accessible/src/atk/nsAppRootAccessible.cpp
+++ b/accessible/src/atk/nsAppRootAccessible.cpp
@@ -46,16 +46,17 @@
#include "nsIServiceManager.h"
#include <gtk/gtk.h>
#include <atk/atk.h>
typedef GType (* AtkGetTypeType) (void);
GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
static PRBool sATKChecked = PR_FALSE;
+static PRLibrary *sATKLib = nsnull;
static PRBool sInitialized = PR_FALSE;
static const char sATKLibName[] = "libatk-1.0.so.0";
static const char sATKHyperlinkImplGetTypeSymbol[] = "atk_hyperlink_impl_get_type";
/* app root accessible */
static nsAppRootAccessible *sAppRoot = nsnull;
/* gail function pointer */
@@ -562,30 +563,36 @@ NS_IMETHODIMP nsAppRootAccessible::Init(
{
sInitialized = PR_FALSE;
NS_IF_RELEASE(sAppRoot);
if (sAtkBridge.lib) {
// Do not shutdown/unload atk-bridge,
// an exit function registered will take care of it
// if (sAtkBridge.shutdown)
// (*sAtkBridge.shutdown)();
+ PR_UnloadLibrary(sAtkBridge.lib);
sAtkBridge.lib = NULL;
sAtkBridge.init = NULL;
sAtkBridge.shutdown = NULL;
}
if (sGail.lib) {
// Do not shutdown gail because
// 1) Maybe it's not init-ed by us. e.g. GtkEmbed
// 2) We need it to avoid assert in spi_atk_tidy_windows
// if (sGail.shutdown)
// (*sGail.shutdown)();
+ PR_UnloadLibrary(sGail.lib);
sGail.lib = NULL;
sGail.init = NULL;
sGail.shutdown = NULL;
}
+ if (sATKLib) {
+ PR_UnloadLibrary(sATKLib);
+ sATKLib = nsnull;
+ }
}
NS_IMETHODIMP nsAppRootAccessible::GetName(nsAString& _retval)
{
nsCOMPtr<nsIStringBundleService> bundleService =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
NS_ASSERTION(bundleService, "String bundle service must be present!");
@@ -815,19 +822,19 @@ nsAppRootAccessible::RemoveRootAccessibl
InvalidateChildren();
return rv;
}
nsAppRootAccessible *
nsAppRootAccessible::Create()
{
if (!sATKChecked) {
- PRLibrary *atkLib = PR_LoadLibrary(sATKLibName);
- if (atkLib) {
- AtkGetTypeType pfn_atk_hyperlink_impl_get_type = (AtkGetTypeType) PR_FindFunctionSymbol(atkLib, sATKHyperlinkImplGetTypeSymbol);
+ sATKLib = PR_LoadLibrary(sATKLibName);
+ if (sATKLib) {
+ AtkGetTypeType pfn_atk_hyperlink_impl_get_type = (AtkGetTypeType) PR_FindFunctionSymbol(sATKLib, sATKHyperlinkImplGetTypeSymbol);
if (pfn_atk_hyperlink_impl_get_type) {
g_atk_hyperlink_impl_type = pfn_atk_hyperlink_impl_get_type();
}
}
sATKChecked = PR_TRUE;
}
if (!sAppRoot && sInitialized) {
sAppRoot = new nsAppRootAccessible();
--- a/extensions/auth/nsAuthFactory.cpp
+++ b/extensions/auth/nsAuthFactory.cpp
@@ -265,9 +265,16 @@ InitNegotiateAuth(nsIModule *self)
{
gNegotiateLog = PR_NewLogModule("negotiateauth");
return NS_OK;
}
#else
#define InitNegotiateAuth nsnull
#endif
-NS_IMPL_NSGETMODULE_WITH_CTOR(nsAuthModule, components, InitNegotiateAuth)
+PR_STATIC_CALLBACK(void)
+DestroyNegotiateAuth(nsIModule *self)
+{
+ nsAuthGSSAPI::Shutdown();
+}
+
+NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(nsAuthModule, components,
+ InitNegotiateAuth, DestroyNegotiateAuth)
--- a/extensions/auth/nsAuthGSSAPI.cpp
+++ b/extensions/auth/nsAuthGSSAPI.cpp
@@ -98,17 +98,17 @@ static const char *gssFuncStr[] = {
"gss_wrap",
"gss_unwrap"
};
#define gssFuncItems NS_ARRAY_LENGTH(gssFuncStr)
static PRFuncPtr gssFunPtr[gssFuncItems];
static PRBool gssNativeImp = PR_TRUE;
-static PRBool gssFunInit = PR_FALSE;
+static PRLibrary* gssLibrary = nsnull;
#define gss_display_status_ptr ((gss_display_status_type)*gssFunPtr[0])
#define gss_init_sec_context_ptr ((gss_init_sec_context_type)*gssFunPtr[1])
#define gss_indicate_mechs_ptr ((gss_indicate_mechs_type)*gssFunPtr[2])
#define gss_release_oid_set_ptr ((gss_release_oid_set_type)*gssFunPtr[3])
#define gss_delete_sec_context_ptr ((gss_delete_sec_context_type)*gssFunPtr[4])
#define gss_import_name_ptr ((gss_import_name_type)*gssFunPtr[5])
#define gss_release_buffer_ptr ((gss_release_buffer_type)*gssFunPtr[6])
@@ -218,17 +218,17 @@ gssInit()
!(KLCacheHasValidTicketsPtr =
PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) {
LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"));
PR_UnloadLibrary(lib);
return NS_ERROR_FAILURE;
}
#endif
- gssFunInit = PR_TRUE;
+ gssLibrary = lib;
return NS_OK;
}
#if defined( PR_LOGGING )
// Generate proper GSSAPI error messages from the major and
// minor status codes.
void
@@ -237,17 +237,17 @@ LogGssError(OM_uint32 maj_stat, OM_uint3
OM_uint32 new_stat;
OM_uint32 msg_ctx = 0;
gss_buffer_desc status1_string;
gss_buffer_desc status2_string;
OM_uint32 ret;
nsCAutoString errorStr;
errorStr.Assign(prefix);
- if (!gssFunInit)
+ if (!gssLibrary)
return;
errorStr += ": ";
do {
ret = gss_display_status_ptr(&new_stat,
maj_stat,
GSS_C_GSS_CODE,
GSS_C_NULL_OID,
@@ -291,17 +291,17 @@ nsAuthGSSAPI::nsAuthGSSAPI(pType package
{ 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
static gss_OID_desc gss_spnego_mech_oid_desc =
{ 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
LOG(("entering nsAuthGSSAPI::nsAuthGSSAPI()\n"));
mComplete = PR_FALSE;
- if (!gssFunInit && NS_FAILED(gssInit()))
+ if (!gssLibrary && NS_FAILED(gssInit()))
return;
mCtx = GSS_C_NO_CONTEXT;
mMechOID = &gss_krb5_mech_oid_desc;
// if the type is kerberos we accept it as default
// and exit
@@ -335,24 +335,33 @@ nsAuthGSSAPI::nsAuthGSSAPI(pType package
}
gss_release_oid_set_ptr(&minstat, &mech_set);
}
}
void
nsAuthGSSAPI::Reset()
{
- if (gssFunInit && mCtx != GSS_C_NO_CONTEXT) {
+ if (gssLibrary && mCtx != GSS_C_NO_CONTEXT) {
OM_uint32 minor_status;
gss_delete_sec_context_ptr(&minor_status, &mCtx, GSS_C_NO_BUFFER);
}
mCtx = GSS_C_NO_CONTEXT;
mComplete = PR_FALSE;
}
+/* static */ void
+nsAuthGSSAPI::Shutdown()
+{
+ if (gssLibrary) {
+ PR_UnloadLibrary(gssLibrary);
+ gssLibrary = nsnull;
+ }
+}
+
NS_IMPL_ISUPPORTS1(nsAuthGSSAPI, nsIAuthModule)
NS_IMETHODIMP
nsAuthGSSAPI::Init(const char *serviceName,
PRUint32 serviceFlags,
const PRUnichar *domain,
const PRUnichar *username,
const PRUnichar *password)
@@ -360,17 +369,17 @@ nsAuthGSSAPI::Init(const char *serviceNa
// we don't expect to be passed any user credentials
NS_ASSERTION(!domain && !username && !password, "unexpected credentials");
// it's critial that the caller supply a service name to be used
NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG);
LOG(("entering nsAuthGSSAPI::Init()\n"));
- if (!gssFunInit)
+ if (!gssLibrary)
return NS_ERROR_NOT_INITIALIZED;
mServiceName = serviceName;
mServiceFlags = serviceFlags;
return NS_OK;
}
NS_IMETHODIMP
@@ -385,17 +394,17 @@ nsAuthGSSAPI::GetNextToken(const void *i
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER;
gss_name_t server;
nsCAutoString userbuf;
nsresult rv;
LOG(("entering nsAuthGSSAPI::GetNextToken()\n"));
- if (!gssFunInit)
+ if (!gssLibrary)
return NS_ERROR_NOT_INITIALIZED;
// If they've called us again after we're complete, reset to start afresh.
if (mComplete)
Reset();
if (mServiceFlags & REQ_DELEGATE)
req_flags |= GSS_C_DELEG_FLAG;
--- a/extensions/auth/nsAuthGSSAPI.h
+++ b/extensions/auth/nsAuthGSSAPI.h
@@ -55,16 +55,18 @@
class nsAuthGSSAPI : public nsIAuthModule
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHMODULE
nsAuthGSSAPI(pType package);
+ static void Shutdown();
+
private:
~nsAuthGSSAPI() { Reset(); }
void Reset();
gss_OID GetOID() { return mMechOID; }
private:
gss_ctx_id_t mCtx;
--- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
+++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
@@ -605,16 +605,18 @@ GConfProxy::~GConfProxy()
{
if (mGConfClient)
g_object_unref(G_OBJECT(mGConfClient));
if (mObservers) {
(void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull);
delete mObservers;
}
+
+ PR_UnloadLibrary(mGConfLib);
}
PRBool
GConfProxy::Init()
{
SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
if (!mSysPrefService)
return PR_FALSE;
--- a/gfx/src/thebes/nsSystemFontsGTK2.cpp
+++ b/gfx/src/thebes/nsSystemFontsGTK2.cpp
@@ -51,49 +51,73 @@
#include <pango/pangox.h>
#include <pango/pango-fontmap.h>
#include <fontconfig/fontconfig.h>
#include "nsSystemFontsGTK2.h"
#include "gfxPlatformGtk.h"
// Glue to avoid build/runtime dependencies on Pango > 1.6
-
+#ifndef THEBES_USE_PANGO_CAIRO
static gboolean
(* PTR_pango_font_description_get_size_is_absolute)(PangoFontDescription*)
= nsnull;
+static PRLibrary *gPangoLib = nsnull;
static void InitPangoLib()
{
static PRBool initialized = PR_FALSE;
if (initialized)
return;
initialized = PR_TRUE;
- PRLibrary* lib = PR_LoadLibrary("libpango-1.0.so");
- if (!lib)
+ gPangoLib = PR_LoadLibrary("libpango-1.0.so");
+ if (!gPangoLib)
return;
PTR_pango_font_description_get_size_is_absolute =
(gboolean (*)(PangoFontDescription*))
- PR_FindFunctionSymbol(lib, "pango_font_description_get_size_is_absolute");
+ PR_FindFunctionSymbol(gPangoLib,
+ "pango_font_description_get_size_is_absolute");
+}
- // leak lib deliberately
+static void
+ShutdownPangoLib()
+{
+ if (gPangoLib) {
+ PR_UnloadLibrary(gPangoLib);
+ gPangoLib = nsnull;
+ }
}
static gboolean
MOZ_pango_font_description_get_size_is_absolute(PangoFontDescription *desc)
{
if (PTR_pango_font_description_get_size_is_absolute) {
return PTR_pango_font_description_get_size_is_absolute(desc);
}
// In old versions of pango, this was always false.
return PR_FALSE;
}
+#else
+static inline void InitPangoLib()
+{
+}
+
+static inline void ShutdownPangoLib()
+{
+}
+
+static inline gboolean
+MOZ_pango_font_description_get_size_is_absolute(PangoFontDescription *desc)
+{
+ pango_font_description_get_size_is_absolute(desc);
+}
+#endif
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
nsSystemFontsGTK2::nsSystemFontsGTK2()
: mDefaultFontName(NS_LITERAL_STRING("sans-serif"))
, mButtonFontName(NS_LITERAL_STRING("sans-serif"))
, mFieldFontName(NS_LITERAL_STRING("sans-serif"))
, mMenuFontName(NS_LITERAL_STRING("sans-serif"))
@@ -176,16 +200,21 @@ nsSystemFontsGTK2::nsSystemFontsGTK2()
gtk_widget_ensure_style(label);
GetSystemFontInfo(label, &mButtonFontName, &mButtonFontStyle);
gtk_widget_destroy(window); // no unref, windows are different
}
+nsSystemFontsGTK2::~nsSystemFontsGTK2()
+{
+ ShutdownPangoLib();
+}
+
nsresult
nsSystemFontsGTK2::GetSystemFontInfo(GtkWidget *aWidget, nsString *aFontName,
gfxFontStyle *aFontStyle) const
{
GtkSettings *settings = gtk_widget_get_settings(aWidget);
aFontStyle->style = FONT_STYLE_NORMAL;
aFontStyle->decorations = FONT_DECORATION_NONE;
--- a/gfx/src/thebes/nsSystemFontsGTK2.h
+++ b/gfx/src/thebes/nsSystemFontsGTK2.h
@@ -40,16 +40,17 @@
#define _NS_SYSTEMFONTSGTK2_H_
#include <gfxFont.h>
class nsSystemFontsGTK2
{
public:
nsSystemFontsGTK2();
+ ~nsSystemFontsGTK2();
nsresult GetSystemFont(nsSystemFontID anID, nsString *aFontName,
gfxFontStyle *aFontStyle) const;
private:
nsresult GetSystemFontInfo(GtkWidget *aWidget, nsString *aFontName,
gfxFontStyle *aFontStyle) const;
--- a/gfx/thebes/public/gfxPangoFonts.h
+++ b/gfx/thebes/public/gfxPangoFonts.h
@@ -60,16 +60,18 @@ class FontSelector;
class gfxPangoTextRun;
class gfxPangoFont : public gfxFont {
public:
gfxPangoFont (const nsAString& aName,
const gfxFontStyle *aFontStyle);
virtual ~gfxPangoFont ();
+ static void Shutdown();
+
virtual const gfxFont::Metrics& GetMetrics();
PangoFontDescription *GetPangoFontDescription() { RealizeFont(); return mPangoFontDesc; }
PangoContext *GetPangoContext() { RealizeFont(); return mPangoCtx; }
void GetMozLang(nsACString &aMozLang);
void GetActualFontFamily(nsACString &aFamily);
PangoFont *GetPangoFont();
--- a/gfx/thebes/src/gfxBeOSPlatform.cpp
+++ b/gfx/thebes/src/gfxBeOSPlatform.cpp
@@ -32,16 +32,17 @@
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "gfxBeOSPlatform.h"
#include "gfxFontconfigUtils.h"
+#include "gfxPangoFonts.h"
#include "gfxImageSurface.h"
#include "gfxBeOSSurface.h"
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
gfxBeOSPlatform::gfxBeOSPlatform()
{
@@ -49,16 +50,18 @@ gfxBeOSPlatform::gfxBeOSPlatform()
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
}
gfxBeOSPlatform::~gfxBeOSPlatform()
{
gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nsnull;
+ gfxPangoFont::Shutdown();
+
#if 0
// It would be nice to do this (although it might need to be after
// the cairo shutdown that happens in ~gfxPlatform). It even looks
// idempotent. But it has fatal assertions that fire if stuff is
// leaked, and we hit them.
FcFini();
#endif
}
--- a/gfx/thebes/src/gfxPangoFonts.cpp
+++ b/gfx/thebes/src/gfxPangoFonts.cpp
@@ -191,63 +191,76 @@ gfxPangoFontGroup::Copy(const gfxFontSty
// Glue to avoid build/runtime dependencies on Pango > 1.6,
// because we like living in 1999
#ifndef THEBES_USE_PANGO_CAIRO
static void
(* PTR_pango_font_description_set_absolute_size)(PangoFontDescription*, double)
= nsnull;
+static PRLibrary *gPangoLib = nsnull;
static void InitPangoLib()
{
static PRBool initialized = PR_FALSE;
if (initialized)
return;
initialized = PR_TRUE;
g_type_init();
- PRLibrary *lib = PR_LoadLibrary("libpango-1.0.so");
- if (!lib)
+ gPangoLib = PR_LoadLibrary("libpango-1.0.so");
+ if (!gPangoLib)
return;
PTR_pango_font_description_set_absolute_size =
(void (*)(PangoFontDescription*, double))
- PR_FindFunctionSymbol(lib, "pango_font_description_set_absolute_size");
+ PR_FindFunctionSymbol(gPangoLib,
+ "pango_font_description_set_absolute_size");
- // leak lib deliberately
-
- lib = nsnull;
+ PRLibrary *lib = nsnull;
int *xft_max_freetype_files_ptr = nsnull;
xft_max_freetype_files_ptr = (int*) PR_FindSymbolAndLibrary("XftMaxFreeTypeFiles", &lib);
if (xft_max_freetype_files_ptr && *xft_max_freetype_files_ptr < 50)
*xft_max_freetype_files_ptr = 50;
if (lib)
PR_UnloadLibrary(lib);
}
static void
+ShutdownPangoLib()
+{
+ if (gPangoLib) {
+ PR_UnloadLibrary(gPangoLib);
+ gPangoLib = nsnull;
+ }
+}
+
+static void
MOZ_pango_font_description_set_absolute_size(PangoFontDescription *desc,
double size)
{
if (PTR_pango_font_description_set_absolute_size) {
PTR_pango_font_description_set_absolute_size(desc, size);
} else {
pango_font_description_set_size(desc,
(gint)(size * 72.0 /
gfxPlatformGtk::DPI()));
}
}
#else
-static void InitPangoLib()
+static inline void InitPangoLib()
{
}
-static void
+static inline void ShutdownPangoLib()
+{
+}
+
+static inline void
MOZ_pango_font_description_set_absolute_size(PangoFontDescription *desc, double size)
{
pango_font_description_set_absolute_size(desc, size);
}
#endif
gfxPangoFont::gfxPangoFont(const nsAString &aName,
const gfxFontStyle *aFontStyle)
@@ -266,16 +279,22 @@ gfxPangoFont::~gfxPangoFont()
if (mPangoFontDesc)
pango_font_description_free(mPangoFontDesc);
if (mCairoFont)
cairo_scaled_font_destroy(mCairoFont);
}
+/* static */ void
+gfxPangoFont::Shutdown()
+{
+ ShutdownPangoLib();
+}
+
static PangoStyle
ThebesStyleToPangoStyle (const gfxFontStyle *fs)
{
if (fs->style == FONT_STYLE_ITALIC)
return PANGO_STYLE_ITALIC;
if (fs->style == FONT_STYLE_OBLIQUE)
return PANGO_STYLE_OBLIQUE;
--- a/gfx/thebes/src/gfxPlatformGtk.cpp
+++ b/gfx/thebes/src/gfxPlatformGtk.cpp
@@ -37,16 +37,17 @@
* ***** END LICENSE BLOCK ***** */
#define PANGO_ENABLE_BACKEND
#define PANGO_ENABLE_ENGINE
#include "gfxPlatformGtk.h"
#include "gfxFontconfigUtils.h"
+#include "gfxPangoFonts.h"
#include "cairo.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "gfxImageSurface.h"
#include "gfxXlibSurface.h"
@@ -87,16 +88,19 @@ gfxPlatformGtk::gfxPlatformGtk()
if (!sFontconfigUtils)
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
}
gfxPlatformGtk::~gfxPlatformGtk()
{
gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nsnull;
+
+ gfxPangoFont::Shutdown();
+
#ifndef THEBES_USE_PANGO_CAIRO
pango_xft_shutdown_display(GDK_DISPLAY(), 0);
#endif
#if 0
// It would be nice to do this (although it might need to be after
// the cairo shutdown that happens in ~gfxPlatform). It even looks
// idempotent. But it has fatal assertions that fire if stuff is
--- a/uriloader/exthandler/unix/nsGNOMERegistry.cpp
+++ b/uriloader/exthandler/unix/nsGNOMERegistry.cpp
@@ -97,24 +97,28 @@ DECL_FUNC_PTR(gnome_vfs_mime_application
DECL_FUNC_PTR(gnome_program_init);
DECL_FUNC_PTR(libgnome_module_info_get);
DECL_FUNC_PTR(gnome_program_get);
static void
CleanUp()
{
// Unload all libraries
- if (gnomeLib)
+ if (gnomeLib) {
PR_UnloadLibrary(gnomeLib);
- if (gconfLib)
+ gnomeLib = nsnull;
+ }
+ if (gconfLib) {
PR_UnloadLibrary(gconfLib);
- if (vfsLib)
+ gconfLib = nsnull;
+ }
+ if (vfsLib) {
PR_UnloadLibrary(vfsLib);
-
- gnomeLib = gconfLib = vfsLib = nsnull;
+ vfsLib = nsnull;
+ }
}
static PRLibrary *
LoadVersionedLibrary(const char* libName, const char* libVersion)
{
char *platformLibName = PR_GetLibraryName(nsnull, libName);
nsCAutoString versionLibName(platformLibName);
versionLibName.Append(libVersion);
--- a/widget/src/gtk/nsSound.cpp
+++ b/widget/src/gtk/nsSound.cpp
@@ -119,16 +119,25 @@ nsSound::Init()
if (!esdref)
return NS_ERROR_FAILURE;
mInited = PR_TRUE;
return NS_OK;
}
+/* static */ void
+nsSound::Shutdown()
+{
+ if (elib) {
+ PR_UnloadLibrary(elib)
+ elib = nsnull;
+ }
+}
+
#define GET_WORD(s, i) (s[i+1] << 8) | s[i]
#define GET_DWORD(s, i) (s[i+3] << 24) | (s[i+2] << 16) | (s[i+1] << 8) | s[i]
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader,
nsISupports *context,
nsresult aStatus,
PRUint32 dataLen,
const PRUint8 *data)
--- a/widget/src/gtk/nsSound.h
+++ b/widget/src/gtk/nsSound.h
@@ -48,16 +48,18 @@
class nsSound : public nsISound,
public nsIStreamLoaderObserver
{
public:
nsSound();
virtual ~nsSound();
+ static void Shutdown();
+
NS_DECL_ISUPPORTS
NS_DECL_NSISOUND
NS_DECL_NSISTREAMLOADEROBSERVER
private:
PRBool mInited;
};
--- a/widget/src/gtk2/nsIdleServiceGTK.cpp
+++ b/widget/src/gtk2/nsIdleServiceGTK.cpp
@@ -63,16 +63,17 @@ static _XScreenSaverAllocInfo_fn _XSSAll
static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nsnull;
NS_IMPL_ISUPPORTS1(nsIdleServiceGTK, nsIIdleService)
nsIdleServiceGTK::nsIdleServiceGTK()
: mXssInfo(nsnull)
{
+ NS_ASSERTION(!xsslib, "created two instances of the idle service");
#ifdef PR_LOGGING
if (!sIdleLog)
sIdleLog = PR_NewLogModule("nsIIdleService");
#endif
xsslib = PR_LoadLibrary("libXss.so.1");
if (!xsslib) // ouch.
{
@@ -98,18 +99,20 @@ nsIdleServiceGTK::nsIdleServiceGTK()
#endif
}
nsIdleServiceGTK::~nsIdleServiceGTK()
{
if (mXssInfo)
XFree(mXssInfo);
- if (xsslib)
+ if (xsslib) {
PR_UnloadLibrary(xsslib);
+ xsslib = nsnull;
+ }
}
NS_IMETHODIMP
nsIdleServiceGTK::GetIdleTime(PRUint32 *aTimeDiff)
{
// Ask xscreensaver about idle time:
int event_base, error_base;
*aTimeDiff = 0;
--- a/widget/src/gtk2/nsSound.cpp
+++ b/widget/src/gtk2/nsSound.cpp
@@ -90,17 +90,17 @@ nsSound::nsSound()
{
mInited = PR_FALSE;
}
nsSound::~nsSound()
{
/* see above comment */
if (esdref != -1) {
- EsdCloseType EsdClose = (EsdCloseType) PR_FindSymbol(elib, "esd_close");
+ EsdCloseType EsdClose = (EsdCloseType) PR_FindFunctionSymbol(elib, "esd_close");
(*EsdClose)(esdref);
esdref = -1;
}
}
NS_IMETHODIMP
nsSound::Init()
{
@@ -112,31 +112,40 @@ nsSound::Init()
if (elib)
return NS_OK;
EsdOpenSoundType EsdOpenSound;
elib = PR_LoadLibrary("libesd.so.0");
if (!elib) return NS_ERROR_FAILURE;
- EsdOpenSound = (EsdOpenSoundType) PR_FindSymbol(elib, "esd_open_sound");
+ EsdOpenSound = (EsdOpenSoundType) PR_FindFunctionSymbol(elib, "esd_open_sound");
if (!EsdOpenSound)
return NS_ERROR_FAILURE;
esdref = (*EsdOpenSound)("localhost");
if (!esdref)
return NS_ERROR_FAILURE;
mInited = PR_TRUE;
return NS_OK;
}
+/* static */ void
+nsSound::Shutdown()
+{
+ if (elib) {
+ PR_UnloadLibrary(elib);
+ elib = nsnull;
+ }
+}
+
#define GET_WORD(s, i) (s[i+1] << 8) | s[i]
#define GET_DWORD(s, i) (s[i+3] << 24) | (s[i+2] << 16) | (s[i+1] << 8) | s[i]
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader,
nsISupports *context,
nsresult aStatus,
PRUint32 dataLen,
const PRUint8 *data)
@@ -254,18 +263,18 @@ NS_IMETHODIMP nsSound::OnStreamComplete(
#if 0
printf("f: %d | c: %d | sps: %li | abps: %li | ba: %d | bps: %d | rate: %li\n",
format, channels, samples_per_sec, avg_bytes_per_sec, block_align, bits_per_sample, rate);
#endif
/* open up connection to esd */
EsdPlayStreamType EsdPlayStream =
- (EsdPlayStreamType) PR_FindSymbol(elib,
- "esd_play_stream");
+ (EsdPlayStreamType) PR_FindFunctionSymbol(elib,
+ "esd_play_stream");
// XXX what if that fails? (Bug 241738)
mask = ESD_PLAY | ESD_STREAM;
if (bits_per_sample == 8)
mask |= ESD_BITS8;
else
mask |= ESD_BITS16;
@@ -293,19 +302,19 @@ NS_IMETHODIMP nsSound::OnStreamComplete(
}
#endif
fd = (*EsdPlayStream)(mask, samples_per_sec, NULL, "mozillaSound");
if (fd < 0) {
int *esd_audio_format = (int *) PR_FindSymbol(elib, "esd_audio_format");
int *esd_audio_rate = (int *) PR_FindSymbol(elib, "esd_audio_rate");
- EsdAudioOpenType EsdAudioOpen = (EsdAudioOpenType) PR_FindSymbol(elib, "esd_audio_open");
- EsdAudioWriteType EsdAudioWrite = (EsdAudioWriteType) PR_FindSymbol(elib, "esd_audio_write");
- EsdAudioCloseType EsdAudioClose = (EsdAudioCloseType) PR_FindSymbol(elib, "esd_audio_close");
+ EsdAudioOpenType EsdAudioOpen = (EsdAudioOpenType) PR_FindFunctionSymbol(elib, "esd_audio_open");
+ EsdAudioWriteType EsdAudioWrite = (EsdAudioWriteType) PR_FindFunctionSymbol(elib, "esd_audio_write");
+ EsdAudioCloseType EsdAudioClose = (EsdAudioCloseType) PR_FindFunctionSymbol(elib, "esd_audio_close");
*esd_audio_format = mask;
*esd_audio_rate = samples_per_sec;
fd = (*EsdAudioOpen)();
if (fd < 0)
return NS_ERROR_FAILURE;
--- a/widget/src/gtk2/nsSound.h
+++ b/widget/src/gtk2/nsSound.h
@@ -48,16 +48,18 @@
class nsSound : public nsISound,
public nsIStreamLoaderObserver
{
public:
nsSound();
virtual ~nsSound();
+ static void Shutdown();
+
NS_DECL_ISUPPORTS
NS_DECL_NSISOUND
NS_DECL_NSISTREAMLOADEROBSERVER
private:
PRBool mInited;
};
--- a/widget/src/gtk2/nsWidgetFactory.cpp
+++ b/widget/src/gtk2/nsWidgetFactory.cpp
@@ -275,16 +275,17 @@ static const nsModuleComponentInfo compo
"@mozilla.org/widget/idleservice;1",
nsIdleServiceGTKConstructor },
};
PR_STATIC_CALLBACK(void)
nsWidgetGtk2ModuleDtor(nsIModule *aSelf)
{
nsFilePicker::Shutdown();
+ nsSound::Shutdown();
nsWindow::ReleaseGlobals();
nsAppShellShutdown(aSelf);
}
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(nsWidgetGtk2Module,
components,
nsAppShellInit,
nsWidgetGtk2ModuleDtor)
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -1007,18 +1007,28 @@ nsWindow::SetCursor(imgIContainer* aCurs
nsWindow *window = get_window_for_gtk_widget(widget);
return window->SetCursor(aCursor, aHotspotX, aHotspotY);
}
if (!sPixbufCursorChecked) {
PRLibrary* lib;
_gdk_cursor_new_from_pixbuf = (_gdk_cursor_new_from_pixbuf_fn)
PR_FindFunctionSymbolAndLibrary("gdk_cursor_new_from_pixbuf", &lib);
+ if (lib) {
+ // We already link against GDK, so we can unload it.
+ PR_UnloadLibrary(lib);
+ lib = nsnull;
+ }
_gdk_display_get_default = (_gdk_display_get_default_fn)
PR_FindFunctionSymbolAndLibrary("gdk_display_get_default", &lib);
+ if (lib) {
+ // We already link against GDK, so we can unload it.
+ PR_UnloadLibrary(lib);
+ lib = nsnull;
+ }
sPixbufCursorChecked = PR_TRUE;
}
mCursor = nsCursor(-1);
// Get first image frame
nsCOMPtr<gfxIImageFrame> frame;
aCursor->GetFrameAt(0, getter_AddRefs(frame));
if (!frame)
--- a/xpcom/io/nsILocalFile.idl
+++ b/xpcom/io/nsILocalFile.idl
@@ -96,19 +96,32 @@ interface nsILocalFile : nsIFile
*
* This attribute will determine if the nsLocalFile will auto
* resolve symbolic links. By default, this value will be false
* on all non unix systems. On unix, this attribute is effectively
* a noop.
*/
attribute PRBool followLinks;
+ /**
+ * Return the result of PR_Open on the file. The caller is
+ * responsible for calling PR_Close on the result.
+ */
[noscript] PRFileDescStar openNSPRFileDesc(in long flags, in long mode);
+
+ /**
+ * Return the result of fopen on the file. The caller is
+ * responsible for calling fclose on the result.
+ */
[noscript] FILE openANSIFileDesc(in string mode);
+ /**
+ * Return the result of PR_LoadLibrary on the file. The caller is
+ * responsible for calling PR_UnloadLibrary on the result.
+ */
[noscript] PRLibraryStar load();
readonly attribute PRInt64 diskSpaceAvailable;
/**
* appendRelative[Native]Path
*
* Append a relative path to the current path of the nsILocalFile object.