|
Boost : |
From: John Max Skaller (skaller_at_[hidden])
Date: 2001-08-15 20:35:39
williamkempf_at_[hidden] wrote:
>
> --- In boost_at_y..., "Alexander Terekhov" <terekhov_at_d...> wrote:
> >
> > > I note the clever semantics: this call would have to
> > > throw an exception if the thread had been detached.
> > > But there's no call to detach a thread, so it cannot happen:
> > > threads are detached simply by not calling join.
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > really? without ref.counting? i do not understand this.
> > can you explain this?
>
> Unfortunately, to implement this correctly on top of pthreads I think
> we're going to have to ref-count. Not in the same manner as you do
> with a thread_ref concept, but it's still going to need to be done.
> The biggest problem I see to getting this right is in not knowing
> precisely what POSIX defines as the result of calling join() on a
> thread that's already been joined or detached. If it's undefined
> behavior then I'm going to have problems with "adopted" threads.
> We'll have to discuss what the appropriate design/implementation will
> be in that case. Can you enlighten me on this issue?
I can't tell you about POSIX. But for 'adopted threads'
I think the solution can be derived as follows:
First, you need to assume that when you take over
a thread you OWN it exclusively (at least until it is
explicitly relinquished).
Second, at the point a thread is adopted,
we're in platform dependent land: you need to adopt
a Windows Handle, or a POSIX thread id, so the interface
is intrinsically platform dependent, unless you abstract
the handle/thread id concept as well (and of course
that just delegates the problem)
Third, when you do adopt a thread, the client
will have to supply the internal state data you need
so that the result is 'as if the thread had been created
and owned by boost all along'. This state data may be platform
specific, and it may also be 'thread library implementation
specific'.
The solution is not to worry about it: just accept that
neither the interface nor implementation will be portable,
and that the client is going to have to learn a bit about
the internal implementation of the thread library they're
using to pass the correct state data.
IF you can do better than
'adopt_thread(.. // implementation defined
that's really good, but I wouldn't worry about it in the first instance.
I suspect you're just going to look at all the state variables in
a thread object, and write a friend that calls a private constructor
that simply initialises them all. If you can refine that
to the point of abstraction with experience of actual usage,
that's great: but I suspect the whole point of adopting threads
is to bypass some of the constraints the threading library
takes as invariants, at least initially, and so it may be up
to the client to establish them: by assumption
a) the invariants were too restrictive for the client
(they needed to make the thread themselves, otherwise
why not use the library in the first place?)
b) the invariants do NOT hold initially
(otherwise why not use the library in the first place)
c) the invariants can be made to hold at the point of
thread adoption by the library (otherwise the library
won't be able to adopt the thread)
d) the invariants are internal implementation details
(otherwise there's no point hiding them inside the
library)
e) there's no choice but to expose some of the implementation
to allow the client to establish the invariants
For example: an initial value for a refcount exposes the existence
of a refcount in the implementation. Too bad. You can't
have abstraction, and also violate its representation invariants
at the same time :-)
-- John (Max) Skaller, mailto:skaller_at_[hidden] 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 New generation programming language Felix http://felix.sourceforge.net Literate Programming tool Interscript http://Interscript.sourceforge.net
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk