* improve locale roster to no longer rely on static object
initialization order This was meant to fix #7227, but just seems to have bypassed it - the crash is now somewhere else ... needs more investigation git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40529 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -114,15 +114,16 @@ struct RosterData {
|
|||||||
bool fAreResourcesLoaded;
|
bool fAreResourcesLoaded;
|
||||||
BResources fResources;
|
BResources fResources;
|
||||||
|
|
||||||
RosterData();
|
status_t fInitStatus;
|
||||||
|
|
||||||
RosterData(const BLanguage& language,
|
RosterData(const BLanguage& language,
|
||||||
const BFormattingConventions& conventions);
|
const BFormattingConventions& conventions);
|
||||||
~RosterData();
|
~RosterData();
|
||||||
|
|
||||||
static RosterData* Default();
|
static RosterData* Default();
|
||||||
|
|
||||||
void InitializeCatalogAddOns();
|
status_t InitCheck() const;
|
||||||
void CleanupCatalogAddOns();
|
|
||||||
status_t Refresh();
|
status_t Refresh();
|
||||||
|
|
||||||
static int CompareInfos(const void* left,
|
static int CompareInfos(const void* left,
|
||||||
@@ -133,6 +134,11 @@ struct RosterData {
|
|||||||
status_t SetDefaultTimeZone(const BTimeZone& zone);
|
status_t SetDefaultTimeZone(const BTimeZone& zone);
|
||||||
status_t SetPreferredLanguages(const BMessage* msg);
|
status_t SetPreferredLanguages(const BMessage* msg);
|
||||||
private:
|
private:
|
||||||
|
status_t _Initialize();
|
||||||
|
|
||||||
|
status_t _InitializeCatalogAddOns();
|
||||||
|
void _CleanupCatalogAddOns();
|
||||||
|
|
||||||
status_t _LoadLocaleSettings();
|
status_t _LoadLocaleSettings();
|
||||||
status_t _SaveLocaleSettings();
|
status_t _SaveLocaleSettings();
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
#include <AppFileInfo.h>
|
#include <AppFileInfo.h>
|
||||||
@@ -126,6 +127,9 @@ CatalogAddOnInfo::UnloadIfPossible()
|
|||||||
// #pragma mark - RosterData
|
// #pragma mark - RosterData
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
static const char* kPriorityAttr = "ADDON:priority";
|
static const char* kPriorityAttr = "ADDON:priority";
|
||||||
|
|
||||||
static const char* kLanguageField = "language";
|
static const char* kLanguageField = "language";
|
||||||
@@ -133,23 +137,28 @@ static const char* kLanguageField = "language";
|
|||||||
static const char* kTimezoneField = "timezone";
|
static const char* kTimezoneField = "timezone";
|
||||||
static const char* kOffsetField = "offset";
|
static const char* kOffsetField = "offset";
|
||||||
|
|
||||||
static RosterData sRosterData(BLanguage("en_US"),
|
|
||||||
BFormattingConventions("en_US"));
|
static RosterData* sRosterData = NULL;
|
||||||
|
static pthread_once_t sRosterDataInitOnce = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
|
static struct RosterDataReaper {
|
||||||
|
~RosterDataReaper()
|
||||||
|
{
|
||||||
|
delete sRosterData;
|
||||||
|
sRosterData = NULL;
|
||||||
|
}
|
||||||
|
} sRosterDataReaper;
|
||||||
|
|
||||||
|
|
||||||
RosterData::RosterData()
|
} // anonymous namespace
|
||||||
:
|
|
||||||
fLock("LocaleRosterData"),
|
|
||||||
fAreResourcesLoaded(false)
|
|
||||||
|
static void
|
||||||
|
InitializeRosterData()
|
||||||
{
|
{
|
||||||
openlog_team("liblocale.so", LOG_PID, LOG_USER);
|
sRosterData = new (std::nothrow) RosterData(BLanguage("en_US"),
|
||||||
#ifndef DEBUG
|
BFormattingConventions("en_US"));
|
||||||
setlogmask_team(LOG_UPTO(LOG_WARNING));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
InitializeCatalogAddOns();
|
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -160,14 +169,7 @@ RosterData::RosterData(const BLanguage& language,
|
|||||||
fDefaultLocale(&language, &conventions),
|
fDefaultLocale(&language, &conventions),
|
||||||
fAreResourcesLoaded(false)
|
fAreResourcesLoaded(false)
|
||||||
{
|
{
|
||||||
openlog_team("liblocale.so", LOG_PID, LOG_USER);
|
fInitStatus = _Initialize();
|
||||||
#ifndef DEBUG
|
|
||||||
setlogmask_team(LOG_UPTO(LOG_WARNING));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
InitializeCatalogAddOns();
|
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -175,7 +177,7 @@ RosterData::~RosterData()
|
|||||||
{
|
{
|
||||||
BAutolock lock(fLock);
|
BAutolock lock(fLock);
|
||||||
|
|
||||||
CleanupCatalogAddOns();
|
_CleanupCatalogAddOns();
|
||||||
closelog();
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,15 +185,17 @@ RosterData::~RosterData()
|
|||||||
/*static*/ RosterData*
|
/*static*/ RosterData*
|
||||||
RosterData::Default()
|
RosterData::Default()
|
||||||
{
|
{
|
||||||
return &sRosterData;
|
if (sRosterData == NULL)
|
||||||
|
pthread_once(&sRosterDataInitOnce, &BPrivate::InitializeRosterData);
|
||||||
|
|
||||||
|
return sRosterData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
status_t
|
||||||
RosterData::CompareInfos(const void* left, const void* right)
|
RosterData::InitCheck() const
|
||||||
{
|
{
|
||||||
return ((CatalogAddOnInfo*)right)->fPriority
|
return fAreResourcesLoaded ? B_OK : B_NO_INIT;
|
||||||
- ((CatalogAddOnInfo*)left)->fPriority;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -208,23 +212,128 @@ RosterData::Refresh()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
RosterData::CompareInfos(const void* left, const void* right)
|
||||||
|
{
|
||||||
|
return ((CatalogAddOnInfo*)right)->fPriority
|
||||||
|
- ((CatalogAddOnInfo*)left)->fPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RosterData::SetDefaultFormattingConventions(
|
||||||
|
const BFormattingConventions& newFormattingConventions)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
BAutolock lock(fLock);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status = _SetDefaultFormattingConventions(newFormattingConventions);
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
status = _SaveLocaleSettings();
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
BMessage updateMessage(B_LOCALE_CHANGED);
|
||||||
|
status = _AddDefaultFormattingConventionsToMessage(&updateMessage);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = be_roster->Broadcast(&updateMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RosterData::SetDefaultTimeZone(const BTimeZone& newZone)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
BAutolock lock(fLock);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status = _SetDefaultTimeZone(newZone);
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
status = _SaveTimeSettings();
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
BMessage updateMessage(B_LOCALE_CHANGED);
|
||||||
|
status = _AddDefaultTimeZoneToMessage(&updateMessage);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = be_roster->Broadcast(&updateMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RosterData::SetPreferredLanguages(const BMessage* languages)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
BAutolock lock(fLock);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status = _SetPreferredLanguages(languages);
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
status = _SaveLocaleSettings();
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
BMessage updateMessage(B_LOCALE_CHANGED);
|
||||||
|
status = _AddPreferredLanguagesToMessage(&updateMessage);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = be_roster->Broadcast(&updateMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RosterData::_Initialize()
|
||||||
|
{
|
||||||
|
openlog_team("liblocale.so", LOG_PID, LOG_USER);
|
||||||
|
#ifndef DEBUG
|
||||||
|
setlogmask_team(LOG_UPTO(LOG_WARNING));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
status_t result = _InitializeCatalogAddOns();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if ((result = Refresh()) != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
fInitStatus = B_OK;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
iterate over add-on-folders and collect information about each
|
iterate over add-on-folders and collect information about each
|
||||||
catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
|
catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
|
||||||
*/
|
*/
|
||||||
void
|
status_t
|
||||||
RosterData::InitializeCatalogAddOns()
|
RosterData::_InitializeCatalogAddOns()
|
||||||
{
|
{
|
||||||
BAutolock lock(fLock);
|
BAutolock lock(fLock);
|
||||||
if (!lock.IsLocked())
|
if (!lock.IsLocked())
|
||||||
return;
|
return B_ERROR;
|
||||||
|
|
||||||
// add info about embedded default catalog:
|
// add info about embedded default catalog:
|
||||||
CatalogAddOnInfo* defaultCatalogAddOnInfo
|
CatalogAddOnInfo* defaultCatalogAddOnInfo
|
||||||
= new(std::nothrow) CatalogAddOnInfo("Default", "",
|
= new(std::nothrow) CatalogAddOnInfo("Default", "",
|
||||||
DefaultCatalog::kDefaultCatalogAddOnPriority);
|
DefaultCatalog::kDefaultCatalogAddOnPriority);
|
||||||
if (!defaultCatalogAddOnInfo)
|
if (!defaultCatalogAddOnInfo)
|
||||||
return;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
|
defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
|
||||||
defaultCatalogAddOnInfo->fInstantiateEmbeddedFunc
|
defaultCatalogAddOnInfo->fInstantiateEmbeddedFunc
|
||||||
@@ -330,6 +439,8 @@ RosterData::InitializeCatalogAddOns()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fCatalogAddOnInfos.SortItems(CompareInfos);
|
fCatalogAddOnInfos.SortItems(CompareInfos);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -337,7 +448,7 @@ RosterData::InitializeCatalogAddOns()
|
|||||||
* unloads all catalog-add-ons (which will throw away all loaded catalogs, too)
|
* unloads all catalog-add-ons (which will throw away all loaded catalogs, too)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RosterData::CleanupCatalogAddOns()
|
RosterData::_CleanupCatalogAddOns()
|
||||||
{
|
{
|
||||||
BAutolock lock(fLock);
|
BAutolock lock(fLock);
|
||||||
if (!lock.IsLocked())
|
if (!lock.IsLocked())
|
||||||
@@ -353,82 +464,6 @@ RosterData::CleanupCatalogAddOns()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
RosterData::SetDefaultFormattingConventions(
|
|
||||||
const BFormattingConventions& newFormattingConventions)
|
|
||||||
{
|
|
||||||
status_t status = B_OK;
|
|
||||||
|
|
||||||
BAutolock lock(fLock);
|
|
||||||
if (!lock.IsLocked())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
status = _SetDefaultFormattingConventions(newFormattingConventions);
|
|
||||||
|
|
||||||
if (status == B_OK)
|
|
||||||
status = _SaveLocaleSettings();
|
|
||||||
|
|
||||||
if (status == B_OK) {
|
|
||||||
BMessage updateMessage(B_LOCALE_CHANGED);
|
|
||||||
status = _AddDefaultFormattingConventionsToMessage(&updateMessage);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = be_roster->Broadcast(&updateMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
RosterData::SetDefaultTimeZone(const BTimeZone& newZone)
|
|
||||||
{
|
|
||||||
status_t status = B_OK;
|
|
||||||
|
|
||||||
BAutolock lock(fLock);
|
|
||||||
if (!lock.IsLocked())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
status = _SetDefaultTimeZone(newZone);
|
|
||||||
|
|
||||||
if (status == B_OK)
|
|
||||||
status = _SaveTimeSettings();
|
|
||||||
|
|
||||||
if (status == B_OK) {
|
|
||||||
BMessage updateMessage(B_LOCALE_CHANGED);
|
|
||||||
status = _AddDefaultTimeZoneToMessage(&updateMessage);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = be_roster->Broadcast(&updateMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
RosterData::SetPreferredLanguages(const BMessage* languages)
|
|
||||||
{
|
|
||||||
status_t status = B_OK;
|
|
||||||
|
|
||||||
BAutolock lock(fLock);
|
|
||||||
if (!lock.IsLocked())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
status = _SetPreferredLanguages(languages);
|
|
||||||
|
|
||||||
if (status == B_OK)
|
|
||||||
status = _SaveLocaleSettings();
|
|
||||||
|
|
||||||
if (status == B_OK) {
|
|
||||||
BMessage updateMessage(B_LOCALE_CHANGED);
|
|
||||||
status = _AddPreferredLanguagesToMessage(&updateMessage);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = be_roster->Broadcast(&updateMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RosterData::_LoadLocaleSettings()
|
RosterData::_LoadLocaleSettings()
|
||||||
{
|
{
|
||||||
@@ -653,9 +688,15 @@ RosterData::_AddPreferredLanguagesToMessage(BMessage* message) const
|
|||||||
// #pragma mark - MutableLocaleRoster
|
// #pragma mark - MutableLocaleRoster
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
static MutableLocaleRoster sLocaleRoster;
|
static MutableLocaleRoster sLocaleRoster;
|
||||||
|
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
MutableLocaleRoster::MutableLocaleRoster()
|
MutableLocaleRoster::MutableLocaleRoster()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user