* 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:
Oliver Tappe 2011-02-16 15:27:33 +00:00
parent 51974c5df0
commit 1d8dff0197
2 changed files with 159 additions and 112 deletions

View File

@ -114,15 +114,16 @@ struct RosterData {
bool fAreResourcesLoaded;
BResources fResources;
RosterData();
status_t fInitStatus;
RosterData(const BLanguage& language,
const BFormattingConventions& conventions);
~RosterData();
static RosterData* Default();
void InitializeCatalogAddOns();
void CleanupCatalogAddOns();
status_t InitCheck() const;
status_t Refresh();
static int CompareInfos(const void* left,
@ -133,6 +134,11 @@ struct RosterData {
status_t SetDefaultTimeZone(const BTimeZone& zone);
status_t SetPreferredLanguages(const BMessage* msg);
private:
status_t _Initialize();
status_t _InitializeCatalogAddOns();
void _CleanupCatalogAddOns();
status_t _LoadLocaleSettings();
status_t _SaveLocaleSettings();

View File

@ -12,6 +12,7 @@
#include <set>
#include <pthread.h>
#include <syslog.h>
#include <AppFileInfo.h>
@ -126,6 +127,9 @@ CatalogAddOnInfo::UnloadIfPossible()
// #pragma mark - RosterData
namespace {
static const char* kPriorityAttr = "ADDON:priority";
static const char* kLanguageField = "language";
@ -133,23 +137,28 @@ static const char* kLanguageField = "language";
static const char* kTimezoneField = "timezone";
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()
:
fLock("LocaleRosterData"),
fAreResourcesLoaded(false)
} // anonymous namespace
static void
InitializeRosterData()
{
openlog_team("liblocale.so", LOG_PID, LOG_USER);
#ifndef DEBUG
setlogmask_team(LOG_UPTO(LOG_WARNING));
#endif
InitializeCatalogAddOns();
Refresh();
sRosterData = new (std::nothrow) RosterData(BLanguage("en_US"),
BFormattingConventions("en_US"));
}
@ -160,14 +169,7 @@ RosterData::RosterData(const BLanguage& language,
fDefaultLocale(&language, &conventions),
fAreResourcesLoaded(false)
{
openlog_team("liblocale.so", LOG_PID, LOG_USER);
#ifndef DEBUG
setlogmask_team(LOG_UPTO(LOG_WARNING));
#endif
InitializeCatalogAddOns();
Refresh();
fInitStatus = _Initialize();
}
@ -175,7 +177,7 @@ RosterData::~RosterData()
{
BAutolock lock(fLock);
CleanupCatalogAddOns();
_CleanupCatalogAddOns();
closelog();
}
@ -183,15 +185,17 @@ RosterData::~RosterData()
/*static*/ RosterData*
RosterData::Default()
{
return &sRosterData;
if (sRosterData == NULL)
pthread_once(&sRosterDataInitOnce, &BPrivate::InitializeRosterData);
return sRosterData;
}
int
RosterData::CompareInfos(const void* left, const void* right)
status_t
RosterData::InitCheck() const
{
return ((CatalogAddOnInfo*)right)->fPriority
- ((CatalogAddOnInfo*)left)->fPriority;
return fAreResourcesLoaded ? B_OK : B_NO_INIT;
}
@ -208,23 +212,128 @@ RosterData::Refresh()
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
catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
*/
void
RosterData::InitializeCatalogAddOns()
status_t
RosterData::_InitializeCatalogAddOns()
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return;
return B_ERROR;
// add info about embedded default catalog:
CatalogAddOnInfo* defaultCatalogAddOnInfo
= new(std::nothrow) CatalogAddOnInfo("Default", "",
DefaultCatalog::kDefaultCatalogAddOnPriority);
if (!defaultCatalogAddOnInfo)
return;
return B_NO_MEMORY;
defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
defaultCatalogAddOnInfo->fInstantiateEmbeddedFunc
@ -330,6 +439,8 @@ RosterData::InitializeCatalogAddOns()
}
}
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)
*/
void
RosterData::CleanupCatalogAddOns()
RosterData::_CleanupCatalogAddOns()
{
BAutolock lock(fLock);
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
RosterData::_LoadLocaleSettings()
{
@ -653,9 +688,15 @@ RosterData::_AddPreferredLanguagesToMessage(BMessage* message) const
// #pragma mark - MutableLocaleRoster
namespace {
static MutableLocaleRoster sLocaleRoster;
} // anonymous namespace
MutableLocaleRoster::MutableLocaleRoster()
{
}