From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-08-31 10:28:40
From: "William Kempf" <williamkempf_at_[hidden]>
> I don't think that "dynamically loaded libraries" have anything to do with
> this. AFAIK, the standard doesn't even mention such things, nor am I
> of the Win32 documentation or POSIX standard mentioning this. The relevant
> part of the standard seems to be 3.6.2/3, which when logically extended to
> include multiple threads of execution means that any dynamically
> object with static storage duration may be initialized in any thread.
You can't 'logically extend' the standard. The standard doesn't talk about
threads. Therefore, we must turn to existing practice. Existing practice -
on every platform that I'm aware of - is to have objects with static storage
duration initialized by the initial thread, _except_ when said object
resides in a dynamically loaded library, in which case the thread that
loaded the library, or implicitly caused the library to load, will
initialize that library's static objects.
Therefore, if thread.cpp is in a statically linked library, its static
objects would get initialized by the initial thread.
> >(1) I think that the current thread design is neither low-level nor
> >high-level, meaning that it doesn't let me say
> >thread t(adopt_main_thread_please_I_take_the_responsibility); // post: t
> Well, I can't recognize the main thread to do this ;).
You don't need to recognize anything. I, the caller, take responsibility
that this constructor is invoked (once) from the main thread.
> However, I guess an
> explicit request to "fully adopt" a thread would work and could be
> on the "initial thread". It would be, however, highly dangerous and
> wouldn't serve much actual utility. I don't see thread_ref as being able
> use this internally, because it won't be able to distinguish the "initial
> thread" from any other "adopted" thread either.
Even if I was able to distinguish the initial thread, what would I do? You
don't let me exploit that knowledge.
> >(2) While I understand your position on the issues where technical
> >with current thread libraries call for an interface that could have been
> >different were you designing a C++ standard library from the scratch, I
> >think that you can afford to move the line a bit. An 'approximation' to
> >ideal implementation that works in 95% of the cases is good enough, as
> >as it's possible to have a 100% implementation with the appropriate
> >from the runtime.
> I definately don't agree with this. It makes usage of the library
I don't think so. No implementation conforms fully.
> since you can't determine when "undefined behavior" occurs (even
> knowing that the 5% occurs when threads are adopted doesn't help the user
> since he doesn't know when a thread is adopted).
There will be no 'undefined behavior.' The interface specification will
demand an implementation that works. The implementation will document the
scenarios that don't work and the workarounds necessary to make them work.
This is not 'undefined behavior' simply because it's defined.
That aside, with your current design the user can't avoid undefined behavior
either because there is no way to check the join() precondition.
> With the stricter
> definitions we get "undefined behavior" with Boost.Threads, but a
> theoretical library based on Boost.Threads that's added to the language
> standard can define the behavior and not break any existing code.
> behavior is only bad when it prevents efficient/effective use, and I don't
> think the current design does this.
I think you have this backwards. Having undefined behavior is never good,
and only acceptable when it's impossible to avoid without compromising
-- Peter Dimov Multi Media Ltd.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk