Boost logo

Boost :

Subject: Re: [boost] [iostreams][io_state_savers] Request for interest in some ios_base basic utilities
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2011-11-10 10:42:28


Artyom Beilis wrote:
>
>> From: Vicente Botet <vicente.botet@>
>>
>>>>>   For example xalloc is thread safe in both MSVC and GCC libraries.
>>>>>
>>>>
>>>>
>>>> I don't like this kind of design, which forces the user to
>> initialize the
>>>> library. I will expect we can do better.
>>>>
>>>
>>> Global constructor?
>>>
>>
>> I don't see what you mean.
>>
>>
>
> I mean that all static ids are installed in global constructor like:
>
> src/foo.cpp
>
> int get_id()
> {
>   static int v = std::ios_base::xalloc();
>   return v;
> }
>
> namespace details {
>   struct installer {
>     installer() { get_id(); }
>   } instance;
> }
>
> This makes sure that if somebody links with the library the
> static ids (facet's ids) and static variables allocated
> with xalloc are installed.
>

Oh, I see. Unfortunately this technique can not be applied when the library
is header-only, isn't it?

> Of course this would not solve problem when two threads
> try dynamically load the same library linked with this one.
>
> But this is quite extreme case.
>
>>>
>>> And singleton can't be done in header only library under dll platform
>>> as
>>> well.
>>>
>>
>> Isn't Boost.Flyweight a header only library?
>>
>>
>
> I'm not familiar with it. So I don't know.
>

Its is quite heavy, but it seems to be working.

>>> So... It is problem. However it is not problem for standard
>>> submission as you always have library - standard c++ library which
>>> by no means can be header only.
>>>
>>
>> Well for the standard submission there is thread or module issue if this
>> state is included directly on the ios state and the default facet is
>> already
>> imbue with the associated facets ;-). Of course this is something I
>> cannot
>> do with Boost.Chorno, or I don't know how to do it :'(.
>>
>
> But you can fallback to default if facet is not installed, i.e.:
>
>    if(!have_facet<foo>(loc))
>         // Do something as std::locale::classic dooes
>    else
>        use_facet<foo>(loc).bar(...)
>
> Same for configuration. Ugly but useful for high level functions.
>

Yes, this is a good technique so that imbuing is not done by the library,
only by the user. However this technique doesn't solves the multi-threaded
imbuing issue.

>>> Now ios state flags should not be thread safe as they stream specific
>>> and I don't expect from user to alter iostream flags from different
>>> threads.
>>>
>>> (*) With ICU not all facets are immutable so in some places I use TLS
>>> to
>>>     improve performance as for example with collator.
>>>
>>
>> Why do you need mutable facets? Isn't this against the locale/facet
>> design?
>>
>> Best,
>> Vicente
>>
>
> It is... But when ICU does not provide immutable collator object and
> cloning collator object is too damn heavy such that it become terribly
> slow then I fallback to TLS and mutate TLS installed objects. Which
> allows be to give reasonable performance while keeping it invisible
> for user and fully thread safe.
>
> For non ICU based facets, there is no such problem.
>

I guess we can define always immutable facets that reference a mutable
storage. Facet should be lightweight so that the creation doesn't takes too
much time.

Thanks for all your comments, very instructive.

Best,
Vicente

--
View this message in context: http://boost.2283326.n4.nabble.com/iostreams-io-state-savers-Request-for-interest-in-some-ios-base-basic-utilities-tp4020844p4024067.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk