Fix relying on order of static object destruction in Locale Kit.

* use only a single static object (MutableLocaleRoster) instead of
  two, which avoids any problems if the order of static object
  destruction would destroy RosterData before MutableLocaleRoster
* rename BPrivate::RosterData to BPrivate::LocaleRosterData and move
  it into a header and implementation file of its own
This should hopefully fix problems encountered with a clang-compiled
Locale Kit.
This commit is contained in:
Oliver Tappe
2012-11-26 01:19:27 +01:00
parent a22e8c6fe2
commit 52cdfde04b
8 changed files with 899 additions and 846 deletions
+15 -1
View File
@@ -21,14 +21,19 @@ class BMessage;
class BTimeZone;
namespace BPrivate {
class LocaleRosterData;
}
enum {
B_LOCALE_CHANGED = '_LCC',
};
class BLocaleRoster {
public:
BLocaleRoster();
~BLocaleRoster();
static BLocaleRoster* Default();
@@ -70,6 +75,8 @@ public:
// Get the catalog for the calling image
// (that needs to link with liblocalestub.a)
const BLocale* GetDefaultLocale() const;
bool IsFilesystemTranslationPreferred() const;
status_t GetLocalizedFileName(BString& localizedFileName,
@@ -83,6 +90,12 @@ public:
static const char* kEmbeddedCatAttr;
static int32 kEmbeddedCatResId;
protected:
BLocaleRoster();
protected:
BPrivate::LocaleRosterData* fData;
private:
static BCatalog* _GetCatalog(BCatalog* catalog,
vint32* catalogInitStatus);
@@ -90,6 +103,7 @@ private:
status_t _PrepareCatalogEntry(const entry_ref& ref,
BString& signature, BString& context,
BString& string, bool traverse);
};
+142
View File
@@ -0,0 +1,142 @@
/*
* Copyright 2010-2012, Haiku. All rights reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef _LOCALE_ROSTER_DATA_H_
#define _LOCALE_ROSTER_DATA_H_
#include <Collator.h>
#include <FormattingConventions.h>
#include <image.h>
#include <Language.h>
#include <List.h>
#include <Locale.h>
#include <Locker.h>
#include <Message.h>
#include <Resources.h>
#include <TimeZone.h>
class BCatalogData;
class BLocale;
struct entry_ref;
namespace BPrivate {
/*
* Struct containing the actual locale data.
*/
struct LocaleRosterData {
BLocker fLock;
BList fCatalogAddOnInfos;
BMessage fPreferredLanguages;
BLocale fDefaultLocale;
BTimeZone fDefaultTimeZone;
bool fIsFilesystemTranslationPreferred;
LocaleRosterData(const BLanguage& language,
const BFormattingConventions& conventions);
~LocaleRosterData();
status_t InitCheck() const;
status_t Refresh();
static int CompareInfos(const void* left,
const void* right);
status_t GetResources(BResources** resources);
status_t SetDefaultFormattingConventions(
const BFormattingConventions& convetions);
status_t SetDefaultTimeZone(const BTimeZone& zone);
status_t SetPreferredLanguages(const BMessage* msg);
status_t SetFilesystemTranslationPreferred(
bool preferred);
private:
status_t _Initialize();
status_t _InitializeCatalogAddOns();
void _CleanupCatalogAddOns();
status_t _LoadLocaleSettings();
status_t _SaveLocaleSettings();
status_t _LoadTimeSettings();
status_t _SaveTimeSettings();
status_t _SetDefaultFormattingConventions(
const BFormattingConventions& conventions);
status_t _SetDefaultTimeZone(const BTimeZone& zone);
status_t _SetPreferredLanguages(const BMessage* msg);
void _SetFilesystemTranslationPreferred(
bool preferred);
status_t _AddDefaultFormattingConventionsToMessage(
BMessage* message) const;
status_t _AddDefaultTimeZoneToMessage(
BMessage* message) const;
status_t _AddPreferredLanguagesToMessage(
BMessage* message) const;
status_t _AddFilesystemTranslationPreferenceToMessage(
BMessage* message) const;
private:
status_t fInitStatus;
bool fAreResourcesLoaded;
BResources fResources;
};
typedef BCatalogData* (*InstantiateCatalogFunc)(const entry_ref& catalogOwner,
const char* language, uint32 fingerprint);
typedef BCatalogData* (*CreateCatalogFunc)(const char* name,
const char* language);
typedef BCatalogData* (*InstantiateEmbeddedCatalogFunc)(
entry_ref* appOrAddOnRef);
typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*,
const char*, int32);
/*
* info about a single catalog-add-on (representing a catalog type):
*/
struct CatalogAddOnInfo {
InstantiateCatalogFunc fInstantiateFunc;
CreateCatalogFunc fCreateFunc;
GetAvailableLanguagesFunc fLanguagesFunc;
BString fName;
BString fPath;
image_id fAddOnImage;
uint8 fPriority;
BList fLoadedCatalogs;
bool fIsEmbedded;
// an embedded add-on actually isn't an
// add-on, it is included as part of the
// library.
// The DefaultCatalog is such a beast!
CatalogAddOnInfo(const BString& name,
const BString& path, uint8 priority);
~CatalogAddOnInfo();
bool MakeSureItsLoaded();
void UnloadIfPossible();
};
} // namespace BPrivate
#endif // _LOCALE_ROSTER_DATA_H_
@@ -60,113 +60,6 @@ public:
};
typedef BCatalogData* (*InstantiateCatalogFunc)(const entry_ref& catalogOwner,
const char* language, uint32 fingerprint);
typedef BCatalogData* (*CreateCatalogFunc)(const char* name,
const char* language);
typedef BCatalogData* (*InstantiateEmbeddedCatalogFunc)(
entry_ref* appOrAddOnRef);
typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*,
const char*, int32);
/*
* info about a single catalog-add-on (representing a catalog type):
*/
struct CatalogAddOnInfo {
InstantiateCatalogFunc fInstantiateFunc;
CreateCatalogFunc fCreateFunc;
GetAvailableLanguagesFunc fLanguagesFunc;
BString fName;
BString fPath;
image_id fAddOnImage;
uint8 fPriority;
BList fLoadedCatalogs;
bool fIsEmbedded;
// an embedded add-on actually isn't an
// add-on, it is included as part of the
// library.
// The DefaultCatalog is such a beast!
CatalogAddOnInfo(const BString& name,
const BString& path, uint8 priority);
~CatalogAddOnInfo();
bool MakeSureItsLoaded();
void UnloadIfPossible();
};
/*
* The global data that is shared between all roster-objects of a process.
*/
struct RosterData {
BLocker fLock;
BList fCatalogAddOnInfos;
BMessage fPreferredLanguages;
BLocale fDefaultLocale;
BTimeZone fDefaultTimeZone;
bool fIsFilesystemTranslationPreferred;
bool fAreResourcesLoaded;
BResources fResources;
status_t fInitStatus;
RosterData(const BLanguage& language,
const BFormattingConventions& conventions);
~RosterData();
static RosterData* Default();
status_t InitCheck() const;
status_t Refresh();
static int CompareInfos(const void* left,
const void* right);
status_t SetDefaultFormattingConventions(
const BFormattingConventions& convetions);
status_t SetDefaultTimeZone(const BTimeZone& zone);
status_t SetPreferredLanguages(const BMessage* msg);
status_t SetFilesystemTranslationPreferred(
bool preferred);
private:
status_t _Initialize();
status_t _InitializeCatalogAddOns();
void _CleanupCatalogAddOns();
status_t _LoadLocaleSettings();
status_t _SaveLocaleSettings();
status_t _LoadTimeSettings();
status_t _SaveTimeSettings();
status_t _SetDefaultFormattingConventions(
const BFormattingConventions& conventions);
status_t _SetDefaultTimeZone(const BTimeZone& zone);
status_t _SetPreferredLanguages(const BMessage* msg);
void _SetFilesystemTranslationPreferred(
bool preferred);
status_t _AddDefaultFormattingConventionsToMessage(
BMessage* message) const;
status_t _AddDefaultTimeZoneToMessage(
BMessage* message) const;
status_t _AddPreferredLanguagesToMessage(
BMessage* message) const;
status_t _AddFilesystemTranslationPreferenceToMessage(
BMessage* message) const;
};
} // namespace BPrivate