[haiku-commits] r37716 - in haiku/trunk: headers/os/locale src/kits/locale

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 23 Jul 2010 13:38:37 +0200 (CEST)

Author: pulkomandy
Date: 2010-07-23 13:38:37 +0200 (Fri, 23 Jul 2010)
New Revision: 37716
Changeset: http://dev.haiku-os.org/changeset/37716

Modified:
   haiku/trunk/headers/os/locale/Country.h
   haiku/trunk/src/kits/locale/Country.cpp
Log:
 * Add locking system to BCountry to avoid problems with the formatters being 
deleted while you use them, or created multiple times.


Modified: haiku/trunk/headers/os/locale/Country.h
===================================================================
--- haiku/trunk/headers/os/locale/Country.h     2010-07-23 10:29:07 UTC (rev 
37715)
+++ haiku/trunk/headers/os/locale/Country.h     2010-07-23 11:38:37 UTC (rev 
37716)
@@ -4,6 +4,7 @@
 
 #include <SupportDefs.h>
 #include <LocaleStrings.h>
+#include <Locker.h>
 #include <String.h>
 
 
@@ -114,14 +115,21 @@
                status_t GetTimeZones(BMessage* timezones);
 
        private:
-               icu_44::DateFormat* DateFormatter(bool longFormat);
-               icu_44::DateFormat* TimeFormatter(bool longFormat);
+               icu_44::DateFormat* LockDateFormatter(bool longFormat);
+               icu_44::DateFormat* LockTimeFormatter(bool longFormat);
+               void                            UnlockDateFormatter(bool 
longFormat);
+               void                            UnlockTimeFormatter(bool 
longFormat);
 
                icu_44::DateFormat* fICULongDateFormatter;
                icu_44::DateFormat* fICUShortDateFormatter;
                icu_44::DateFormat* fICULongTimeFormatter;
                icu_44::DateFormat* fICUShortTimeFormatter;
                icu_44::Locale* fICULocale;
+
+               BLocker fLongDateLock;
+               BLocker fShortDateLock;
+               BLocker fLongTimeLock;
+               BLocker fShortTimeLock;
 };
 
 #endif /* _COUNTRY_H_ */

Modified: haiku/trunk/src/kits/locale/Country.cpp
===================================================================
--- haiku/trunk/src/kits/locale/Country.cpp     2010-07-23 10:29:07 UTC (rev 
37715)
+++ haiku/trunk/src/kits/locale/Country.cpp     2010-07-23 11:38:37 UTC (rev 
37716)
@@ -100,6 +100,11 @@
        if (this == &other)
                return *this;
 
+       fLongDateLock.Lock();
+       fShortDateLock.Lock();
+       fLongTimeLock.Lock();
+       fShortTimeLock.Lock();
+
        delete fICULongTimeFormatter;
        delete fICUShortTimeFormatter;
        delete fICULongDateFormatter;
@@ -115,6 +120,11 @@
        fICULongTimeFormatter = NULL;
        fICUShortTimeFormatter = NULL;
 
+       fShortTimeLock.Unlock();
+       fLongTimeLock.Unlock();
+       fShortDateLock.Unlock();
+       fLongDateLock.Unlock();
+
        return *this;
 }
 
@@ -185,17 +195,19 @@
 
 
 DateFormat*
-BCountry::DateFormatter(bool longFormat)
+BCountry::LockDateFormatter(bool longFormat)
 {
        // TODO: ICU allows for 4 different levels of expansion :
        // short, medium, long, and full. Our bool parameter is not enough...
        if (longFormat) {
+               fLongDateLock.Lock();
                if (fICULongDateFormatter == NULL) {
                        fICULongDateFormatter = DateFormat::createDateInstance(
                                DateFormat::FULL, *fICULocale);
                }
                return fICULongDateFormatter;
        } else {
+               fShortDateLock.Lock();
                if (fICUShortDateFormatter == NULL) {
                        fICUShortDateFormatter = DateFormat::createDateInstance(
                                DateFormat::SHORT, *fICULocale);
@@ -205,18 +217,31 @@
 }
 
 
+void
+BCountry::UnlockDateFormatter(bool longFormat)
+{
+       if (longFormat) {
+               fLongDateLock.Unlock();
+       } else {
+               fShortDateLock.Unlock();
+       }
+}
+
+
 DateFormat*
-BCountry::TimeFormatter(bool longFormat)
+BCountry::LockTimeFormatter(bool longFormat)
 {
        // TODO: ICU allows for 4 different levels of expansion :
        // short, medium, long, and full. Our bool parameter is not enough...
        if (longFormat) {
+               fLongTimeLock.Lock();
                if (fICULongTimeFormatter == NULL) {
                        fICULongTimeFormatter = DateFormat::createTimeInstance(
                                DateFormat::MEDIUM, *fICULocale);
                }
                return fICULongTimeFormatter;
        } else {
+               fShortTimeLock.Lock();
                if (fICUShortTimeFormatter == NULL) {
                        fICUShortTimeFormatter = DateFormat::createTimeInstance(
                                DateFormat::SHORT, *fICULocale);
@@ -226,16 +251,31 @@
 }
 
 
+void
+BCountry::UnlockTimeFormatter(bool longFormat)
+{
+       if (longFormat) {
+               fLongTimeLock.Unlock();
+       } else {
+               fShortTimeLock.Unlock();
+       }
+}
+
+
 status_t
 BCountry::FormatDate(char* string, size_t maxSize, time_t time, bool 
longFormat)
 {
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        UnicodeString ICUString;
        ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
 
+       UnlockDateFormatter(longFormat);
+
        CheckedArrayByteSink stringConverter(string, maxSize);
 
        ICUString.toUTF8(stringConverter);
@@ -253,12 +293,15 @@
        string->Truncate(0);
                // We make the string empty, this way even in cases where ICU 
fail we at
                // least return something sane
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        UnicodeString ICUString;
        ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
+       UnlockDateFormatter(longFormat);
 
        BStringByteSink stringConverter(string);
 
@@ -274,16 +317,19 @@
 {
        string->Truncate(0);
 
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        fieldPositions = NULL;
        UErrorCode error = U_ZERO_ERROR;
        ICU_VERSION::FieldPositionIterator positionIterator;
        UnicodeString ICUString;
-       ICUString = DateFormatter(longFormat)->format((UDate)time * 1000, 
ICUString,
+       ICUString = dateFormatter->format((UDate)time * 1000, ICUString,
                &positionIterator, error);
+       UnlockDateFormatter(longFormat);
 
        if (error != U_ZERO_ERROR)
                return B_ERROR;
@@ -315,15 +361,18 @@
 {
        format.Truncate(0);
 
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        SimpleDateFormat* dateFormatterImpl
                = static_cast<SimpleDateFormat*>(dateFormatter);
 
        UnicodeString ICUString;
        ICUString = dateFormatterImpl->toPattern(ICUString);
+       UnlockDateFormatter(longFormat);
 
        BStringByteSink stringConverter(&format);
 
@@ -336,15 +385,18 @@
 status_t
 BCountry::SetDateFormat(const char* formatString, bool longFormat)
 {
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        SimpleDateFormat* dateFormatterImpl
                = static_cast<SimpleDateFormat*>(dateFormatter);
 
        UnicodeString pattern(formatString);
        dateFormatterImpl->applyPattern(pattern);
+       UnlockDateFormatter(longFormat);
 
        return B_OK;
 }
@@ -353,9 +405,11 @@
 status_t
 BCountry::DateFields(BDateElement*& fields, int& fieldCount, bool longFormat)
 {
-       ICU_VERSION::DateFormat* dateFormatter = DateFormatter(longFormat);
-       if (dateFormatter == NULL)
+       ICU_VERSION::DateFormat* dateFormatter = LockDateFormatter(longFormat);
+       if (dateFormatter == NULL) {
+               UnlockDateFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        fields = NULL;
        UErrorCode error = U_ZERO_ERROR;
@@ -364,6 +418,7 @@
        time_t now;
        ICUString = dateFormatter->format((UDate)time(&now) * 1000, ICUString,
                &positionIterator, error);
+       UnlockDateFormatter(longFormat);
 
        if (error != U_ZERO_ERROR)
                return B_ERROR;
@@ -422,12 +477,15 @@
 status_t
 BCountry::FormatTime(char* string, size_t maxSize, time_t time, bool 
longFormat)
 {
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        UnicodeString ICUString;
        ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
+       UnlockTimeFormatter(longFormat);
 
        CheckedArrayByteSink stringConverter(string, maxSize);
 
@@ -445,12 +503,15 @@
 {
        string->Truncate(0);
 
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        UnicodeString ICUString;
        ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
+       UnlockTimeFormatter(longFormat);
 
        BStringByteSink stringConverter(string);
 
@@ -466,9 +527,11 @@
 {
        string->Truncate(0);
 
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        fieldPositions = NULL;
        UErrorCode error = U_ZERO_ERROR;
@@ -476,6 +539,7 @@
        UnicodeString ICUString;
        ICUString = timeFormatter->format((UDate)time * 1000, ICUString,
                &positionIterator, error);
+       UnlockTimeFormatter(longFormat);
 
        if (error != U_ZERO_ERROR)
                return B_ERROR;
@@ -505,9 +569,11 @@
 status_t
 BCountry::TimeFields(BDateElement*& fields, int& fieldCount, bool longFormat)
 {
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        fields = NULL;
        UErrorCode error = U_ZERO_ERROR;
@@ -516,6 +582,7 @@
        time_t now;
        ICUString = timeFormatter->format((UDate)time(&now) * 1000,     
ICUString,
                &positionIterator, error);
+       UnlockTimeFormatter(longFormat);
 
        if (error != U_ZERO_ERROR)
                return B_ERROR;
@@ -560,15 +627,18 @@
 status_t
 BCountry::SetTimeFormat(const char* formatString, bool longFormat)
 {
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        SimpleDateFormat* dateFormatterImpl
                = static_cast<SimpleDateFormat*>(timeFormatter);
 
        UnicodeString pattern(formatString);
        dateFormatterImpl->applyPattern(pattern);
+       UnlockTimeFormatter(longFormat);
 
        return B_OK;
 }
@@ -577,15 +647,18 @@
 status_t
 BCountry::TimeFormat(BString& format, bool longFormat)
 {
-       ICU_VERSION::DateFormat* timeFormatter = TimeFormatter(longFormat);
-       if (timeFormatter == NULL)
+       ICU_VERSION::DateFormat* timeFormatter = LockTimeFormatter(longFormat);
+       if (timeFormatter == NULL) {
+               UnlockTimeFormatter(longFormat);
                return B_NO_MEMORY;
+       }
 
        SimpleDateFormat* dateFormatterImpl
                = static_cast<SimpleDateFormat*>(timeFormatter);
 
        UnicodeString ICUString;
        ICUString = dateFormatterImpl->toPattern(ICUString);
+       UnlockTimeFormatter(longFormat);
 
        BStringByteSink stringConverter(&format);
 


Other related posts: