From: "Daniel P. Berrange" <berrange@redhat.com>
To: Alberto Garcia <berto@igalia.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] QEMU produces invalid JSON due to locale-dependent code
Date: Wed, 26 Aug 2015 10:22:36 +0100 [thread overview]
Message-ID: <20150826092236.GC21787@redhat.com> (raw)
In-Reply-To: <w518u8yv2eb.fsf@maestria.local.igalia.com>
On Wed, Aug 26, 2015 at 11:13:00AM +0200, Alberto Garcia wrote:
> On Tue 25 Aug 2015 09:54:42 AM CEST, Markus Armbruster wrote:
>
> >> (D) Run in a controlled mixed locale
> >> GTK runs completely in the locale determined by setlocale() (since it
> >> never has to display raw JSON)
> >> We fix our JSON output code to use thread-specific locale
> >> manipulations to (temporarily) switch to C locale before printing JSON
> >>
> >> that way, GTK still shows full German formatting for any localized
> >> message in the GUI that happens to print numbers, but the JSON output
> >> (which is independent of the GUI) also behaves correctly as a C-only
> >> entity.
> >
> > Switching back to C locale whenever some unwanted locale-dependency
> > breaks the code is problematic, because it involves finding all the
> > places that break, iteratively (euphemism for "we debug one breakage
> > after the other, adding temporary locale switches as we go).
>
> For some cases we probably don't even need to switch the locale. For the
> JSON case cannot we just easily convert the QFloat into a string
> ourselves without using printf's "%f" ?
FWIW, libvirt had this exact same problem with formatting doubles for
JSON while non-C locales are in effect. We used the glibc thread-local
locale support, and fallback to some sick string munging in non-glibc
case:
/* In case thread-safe locales are available */
#if HAVE_NEWLOCALE
static locale_t virLocale;
static int
virLocaleOnceInit(void)
{
virLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
if (!virLocale)
return -1;
return 0;
}
VIR_ONCE_GLOBAL_INIT(virLocale)
#endif
/**
* virDoubleToStr
*
* converts double to string with C locale (thread-safe).
*
* Returns -1 on error, size of the string otherwise.
*/
int
virDoubleToStr(char **strp, double number)
{
int ret = -1;
#if HAVE_NEWLOCALE
locale_t old_loc;
if (virLocaleInitialize() < 0)
goto error;
old_loc = uselocale(virLocale);
ret = virAsprintf(strp, "%lf", number);
uselocale(old_loc);
#else
char *radix, *tmp;
struct lconv *lc;
if ((ret = virVasprintf(strp, "%lf", number) < 0)
goto error;
lc = localeconv();
radix = lc->decimal_point;
tmp = strstr(*strp, radix);
if (tmp) {
*tmp = '.';
if (strlen(radix) > 1)
memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - str));
}
#endif /* HAVE_NEWLOCALE */
error:
return ret;
}
> That doesn't invalidate however your point.
>
> > I'd feel much better about confining GTK in its own thread, and
> > setting only that thread's locale.
>
> I haven't digged much into that part of the QEMU code, but if my
> assumptions are true I think we would need at least:
>
> - A separate GMainContext with its own main loop
> - Making sure that all the code that touches the UI runs from that
> thread.
>
> This is in principle possible, but I fear that we might be opening a can
> of worms.
Agreed, my experiance is that you should always run GTK in the main
thread and never try todo anything more clever with threads + GTK.
It has always ended in tears for me - even if you think you have it
working on your system, you'll inevitably find a different version
of GTK where it has broken. It just isn't worth the pain to try to
run anything GTK related in a non-main thread.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
next prev parent reply other threads:[~2015-08-26 9:22 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-18 23:57 [Qemu-devel] QEMU produces invalid JSON due to locale-dependent code Alberto Garcia
2015-08-24 8:58 ` Daniel P. Berrange
2015-08-24 10:05 ` Markus Armbruster
2015-08-24 10:29 ` Alberto Garcia
2015-08-24 17:07 ` Markus Armbruster
2015-08-24 17:18 ` Eric Blake
2015-08-25 7:54 ` Markus Armbruster
2015-08-25 8:15 ` Alberto Garcia
2015-08-25 12:51 ` Markus Armbruster
2015-08-26 9:13 ` Alberto Garcia
2015-08-26 9:22 ` Daniel P. Berrange [this message]
2015-08-26 9:47 ` Markus Armbruster
2015-08-24 17:56 ` Daniel P. Berrange
2015-08-24 20:27 ` Eric Blake
2015-08-26 6:46 ` Gerd Hoffmann
2015-08-26 9:57 ` Daniel P. Berrange
2015-08-26 12:04 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150826092236.GC21787@redhat.com \
--to=berrange@redhat.com \
--cc=armbru@redhat.com \
--cc=berto@igalia.com \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).