Bug 792105 - Startup takes several minutes, take two.

First, remove the unnecessary locale push & pop on <CT_TIME64>load.

Second, the registry accesses were caused by using g_win32_get_locale
to convert the Microsoft locale strings to POSIX ones. We don't care
what kind of string we get as long as we can pass it back to setlocale,
so remove that.

Third, gnc_push/pop_locale were used only in backend/dbi in a
very limited way and did much more than was necessary, so
convert them to C++ inlines in gnc-backend-dbi.hpp that does
only what we need them to.
pull/341/head
John Ralls 8 years ago
parent 39aecb7610
commit cad6bb4272

@ -1177,7 +1177,7 @@ dbi_library_test (dbi_conn conn)
return GNC_DBI_FAIL_SETUP;
}
dbi_result_free (result);
gnc_push_locale (LC_NUMERIC, "C");
auto locale = gnc_push_locale (LC_NUMERIC, "C");
result = dbi_conn_query (conn, "SELECT * FROM numtest");
if (result == nullptr)
{
@ -1186,7 +1186,7 @@ dbi_library_test (dbi_conn conn)
PWARN ("Test_DBI_Library: Failed to retrieve test row into table: %s",
errmsg);
dbi_conn_query (conn, "DROP TABLE numtest");
gnc_pop_locale (LC_NUMERIC);
gnc_pop_locale (LC_NUMERIC, locale);
return GNC_DBI_FAIL_SETUP;
}
while (dbi_result_next_row (result))
@ -1196,7 +1196,7 @@ dbi_library_test (dbi_conn conn)
resultdouble = dbi_result_get_double (result, "test_double");
}
dbi_conn_query (conn, "DROP TABLE numtest");
gnc_pop_locale (LC_NUMERIC);
gnc_pop_locale (LC_NUMERIC, locale);
if (testlonglong != resultlonglong)
{
PWARN ("Test_DBI_Library: LongLong Failed %" PRId64 " != % " PRId64,

@ -118,6 +118,21 @@ private:
bool m_exists; // Does the database exist?
};
/* locale-stack */
inline std::string
gnc_push_locale(const int category, const std::string locale)
{
std::string retval(setlocale(category, nullptr));
setlocale(category, locale.c_str());
return retval;
}
inline void
gnc_pop_locale(const int category, std::string locale)
{
setlocale(category, locale.c_str());
}
/* external access required for tests */
std::string adjust_sql_options_string(const std::string&);

@ -252,7 +252,7 @@ GncDbiSqlConnection::execute_select_statement (const GncSqlStatementPtr& stmt)
dbi_result result;
DEBUG ("SQL: %s\n", stmt->to_sql());
gnc_push_locale (LC_NUMERIC, "C");
auto locale = gnc_push_locale (LC_NUMERIC, "C");
do
{
init_error ();
@ -261,7 +261,7 @@ GncDbiSqlConnection::execute_select_statement (const GncSqlStatementPtr& stmt)
while (m_retry);
if (result == nullptr)
PERR ("Error executing SQL %s\n", stmt->to_sql());
gnc_pop_locale (LC_NUMERIC);
gnc_pop_locale (LC_NUMERIC, locale);
return GncSqlResultPtr(new GncDbiSqlResult (this, result));
}

@ -117,9 +117,9 @@ GncDbiSqlResult::IteratorImpl::get_float_at_col(const char* col) const
if(type != DBI_TYPE_DECIMAL ||
(attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE4)
throw (std::invalid_argument{"Requested float from non-float column."});
gnc_push_locale (LC_NUMERIC, "C");
auto locale = gnc_push_locale (LC_NUMERIC, "C");
auto retval = dbi_result_get_float(m_inst->m_dbi_result, col);
gnc_pop_locale (LC_NUMERIC);
gnc_pop_locale (LC_NUMERIC, locale);
return retval;
}
@ -131,9 +131,9 @@ GncDbiSqlResult::IteratorImpl::get_double_at_col(const char* col) const
if(type != DBI_TYPE_DECIMAL ||
(attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE8)
throw (std::invalid_argument{"Requested double from non-double column."});
gnc_push_locale (LC_NUMERIC, "C");
auto locale = gnc_push_locale (LC_NUMERIC, "C");
auto retval = dbi_result_get_double(m_inst->m_dbi_result, col);
gnc_pop_locale (LC_NUMERIC);
gnc_pop_locale (LC_NUMERIC, locale);
return retval;
}
@ -160,7 +160,6 @@ GncDbiSqlResult::IteratorImpl::get_time64_at_col (const char* col) const
auto attrs = dbi_result_get_field_attribs (result, col);
if (type != DBI_TYPE_DATETIME)
throw (std::invalid_argument{"Requested time64 from non-time64 column."});
gnc_push_locale (LC_NUMERIC, "C");
#if HAVE_LIBDBI_TO_LONGLONG
/* A less evil hack than the one required by libdbi-0.8, but
* still necessary to work around the same bug.
@ -179,7 +178,6 @@ GncDbiSqlResult::IteratorImpl::get_time64_at_col (const char* col) const
#endif //HAVE_LIBDBI_TO_LONGLONG
if (retval < MINTIME || retval > MAXTIME)
retval = 0;
gnc_pop_locale (LC_NUMERIC);
return retval;
}

@ -150,43 +150,3 @@ gnc_locale_decimal_places (void)
return places;
}
static GList *locale_stack = NULL;
void
gnc_push_locale (int category, const char *locale)
{
char *saved_locale;
g_return_if_fail (locale != NULL);
# ifdef G_OS_WIN32
/* On win32, setlocale() doesn't say anything useful. Use
glib's function instead. */
saved_locale = g_win32_getlocale();
# else
saved_locale = g_strdup(setlocale(category, NULL) ?
setlocale(category, NULL) : "C");
#endif
locale_stack = g_list_prepend (locale_stack, saved_locale);
setlocale (category, locale);
}
void
gnc_pop_locale (int category)
{
char *saved_locale;
GList *node;
g_return_if_fail (locale_stack != NULL);
node = locale_stack;
saved_locale = node->data;
setlocale (category, saved_locale);
locale_stack = g_list_remove_link (locale_stack, node);
g_list_free_1 (node);
g_free (saved_locale);
}

@ -37,26 +37,4 @@ const char * gnc_locale_default_iso_currency_code (void);
/* Returns the number of decimal place to print in the current locale */
int gnc_locale_decimal_places (void);
/** Temporarily change locale, pushing the old one onto a stack
* Currently, this has no effect on gnc_localeconv. i.e., after the
* first call to gnc_localeconv, subsequent calls will return the same
* information.
*
* WARNING: Be careful to maintain the correct nesting order of pushes
* or pops; otherwise, the localization results might be
* interesting. Note that the stack does not keep track of which
* category a locale was pushed from, so careless use will alse
* produce interesting results.
*
* @param category: The locale category (e.g. LC_ALL, LC_NUMERIC) to push onto
* @param locale: The new locale to set
*/
void gnc_push_locale (int category, const char *locale);
/** Restore the last-pushed locale.
* @param category: The locale category to restore the locale to.
*/
void gnc_pop_locale (int category);
#endif /* GNC_LOCALE_UTILS_H */

Loading…
Cancel
Save