LocaleRoster: race condition on catalog loading.
Using a vint32 isn't enough to safely decide if the catalog is initialized or not. Use init_once features instead.
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
#define _LOCALE_ROSTER_H_
|
#define _LOCALE_ROSTER_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static BCatalog* _GetCatalog(BCatalog* catalog,
|
static BCatalog* _GetCatalog(BCatalog* catalog,
|
||||||
vint32* catalogInitStatus);
|
int32* catalogInitStatus);
|
||||||
|
|
||||||
status_t _PrepareCatalogEntry(const entry_ref& ref,
|
status_t _PrepareCatalogEntry(const entry_ref& ref,
|
||||||
BString& signature, BString& context,
|
BString& signature, BString& context,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>.
|
* Copyright 2010-2014, Adrien Destugues <pulkomandy@pulkomandy.tk>.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,9 +7,11 @@
|
|||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <LocaleRoster.h>
|
#include <LocaleRoster.h>
|
||||||
|
|
||||||
|
#include <locks.h>
|
||||||
|
|
||||||
|
|
||||||
static BCatalog sCatalog;
|
static BCatalog sCatalog;
|
||||||
static vint32 sCatalogInitOnce = false;
|
static int32 sCatalogInitOnce = INIT_ONCE_UNINITIALIZED;
|
||||||
|
|
||||||
|
|
||||||
BCatalog*
|
BCatalog*
|
||||||
@@ -28,7 +30,7 @@ BLocaleRoster::GetCatalog()
|
|||||||
namespace BPrivate{
|
namespace BPrivate{
|
||||||
void ForceUnloadCatalog()
|
void ForceUnloadCatalog()
|
||||||
{
|
{
|
||||||
sCatalogInitOnce = false;
|
sCatalogInitOnce = INIT_ONCE_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <TimeZone.h>
|
#include <TimeZone.h>
|
||||||
|
|
||||||
#include <ICUWrapper.h>
|
#include <ICUWrapper.h>
|
||||||
|
#include <locks.h>
|
||||||
|
|
||||||
// ICU includes
|
// ICU includes
|
||||||
#include <unicode/locdspnm.h>
|
#include <unicode/locdspnm.h>
|
||||||
@@ -515,16 +516,10 @@ BLocaleRoster::GetLocalizedFileName(BString& localizedFileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BCatalog*
|
static status_t
|
||||||
BLocaleRoster::_GetCatalog(BCatalog* catalog, vint32* catalogInitStatus)
|
_InitializeCatalog(void* param)
|
||||||
{
|
{
|
||||||
// This function is used in the translation macros, so it can't return a
|
BCatalog* catalog = (BCatalog*)param;
|
||||||
// status_t. Maybe it could throw exceptions ?
|
|
||||||
|
|
||||||
if (*catalogInitStatus == true) {
|
|
||||||
// Catalog already loaded - nothing else to do
|
|
||||||
return catalog;
|
|
||||||
}
|
|
||||||
|
|
||||||
// figure out image (shared object) from catalog address
|
// figure out image (shared object) from catalog address
|
||||||
image_info info;
|
image_info info;
|
||||||
@@ -540,13 +535,24 @@ BLocaleRoster::_GetCatalog(BCatalog* catalog, vint32* catalogInitStatus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
return catalog;
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
// load the catalog for this mimetype and return it to the app
|
// load the catalog for this mimetype
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
if (BEntry(info.name).GetRef(&ref) == B_OK && catalog->SetTo(ref) == B_OK)
|
if (BEntry(info.name).GetRef(&ref) == B_OK && catalog->SetTo(ref) == B_OK);
|
||||||
*catalogInitStatus = true;
|
return B_OK;
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCatalog*
|
||||||
|
BLocaleRoster::_GetCatalog(BCatalog* catalog, int32* catalogInitStatus)
|
||||||
|
{
|
||||||
|
// This function is used in the translation macros, so it can't return a
|
||||||
|
// status_t. Maybe it could throw exceptions ?
|
||||||
|
|
||||||
|
__init_once(catalogInitStatus, _InitializeCatalog, catalog);
|
||||||
return catalog;
|
return catalog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user