|
Boost : |
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2003-01-09 12:22:42
"William E. Kempf" wrote:
[...]
> > I think that a reasonable requirement that we already mentioned several
> > times is that the ID should be CopyConstructible, Assignable and
> > LessThanComparable, for use in sets/maps.
>
> This misses the need for outputting in diagnostic messages, for one thing.
> And all of this can be supplied directly by boost::thread with no need for
> a boost::thead::id. I just want to make sure we've not missed some other
> need, which may mean we DO need a seperate id type.
I, for one, DO need something along the lines of:
http://groups.google.com/groups?selm=3D613D44.9B67916%40web.de
(Subject: Re: High level thread design question)
Well, "futures" aside for a moment, how about the following "concept"
(just an illustration/ideas):
new_thread{< thread >}( function{, ...args...} );
{exception_propagator< exception{, ...exceptions...} >::}
{thread_attr_object.}new_thread( function{, args} );
{exception_propagator< thread, exception{, ...exceptions...} >::}
{thread_attr_object.}new_thread( function{, args} );
For example, given:
void operation(); // Oh, BTW, in the next release this might throw std::bad_alloc
We could then have:
a) no propagation of exceptions on join ["default"]:
new_thread( operation );
new_thread< my_fancy_thread >( operation );
thread::attr().set_name( "007" ).
new_thread( operation );
my_fancy_thread::attr().set_something( something ).
new_thread( operation );
b) propagation of exceptions [specified at thread CREATION point] on join:
exception_propagator< std::bad_alloc >::
new_thread( operation );
exception_propagator< my_fancy_thread,std::bad_alloc >::
new_thread( operation );
exception_propagator< std::bad_alloc >::
attr().set_name( "007" ).
new_thread( operation );
exception_propagator< my_fancy_thread,std::bad_alloc >::
attr().set_something( something ).
new_thread( operation );
where "my_fancy_thread" would be something along the lines of:
class my_fancy_thread : public thread {
public:
class attr : public thread::attr {
public: /*...add some fancy stuff...*/ };
/*...add some fancy stuff...*/ };
(with "thread fields", custom on_thread_start() and
on_thread_termination() "hooks", etc. )
Basically, the idea is to use "exception_propagator" beast to communicate
the typelist of exceptions that need to be caught, stored and propagated
on join to the "thread" template -- it would simply have discriminated
union for storing result (void* for void functions; just to have
"something" instead of void) PLUS all exceptions from that typelist.
This typelist should be properly ordered and will be used for "generic"
catch-and-store-it-in-a-union "finalization" in the launching/landing
pad routine. Join operations would simply fire a "visitor pattern" to
throw this or that exception caught and stored in the joinee thread.
Generic code would have to be parameterized to let users specify a
typelist containing any exception types s/he wants to catch-and-
propagate-on-join for this or that async. "operation" invocation.
Well, I'd also probably could live with something along the lines of:
(ES: exception specification/throw({...})-spec; ES_stuff_only: things
specified in the ES excluding thread_cancel and thread_exit exceptions;
well, I'm somewhat unsure with respect to thread_restart exception ;-) )
new_thread_that_will_propagate_on_join_ES_stuff_only( operation );
new_thread_that_will_propagate_on_join_ES_stuff_only<
my_fancy_thread >( operation );
thread::attr().set_name( "007" ).
new_thread_that_will_propagate_on_join_ES_stuff_only( operation );
my_fancy_thread::attr().set_something( something ).
new_thread_that_will_propagate_on_join_ES_stuff_only( operation );
but I don't think that this can be done in the current C++... its
standard-required-and-utterly-silly unwinding on ES violations aside
for a moment.
http://groups.google.com/groups?selm=3D514E1B.E3CF5716%40web.de
(Subject: Boost.Thread: "Threads & Exceptions"/"Enhanced call_once()")
Peter Dimov wrote:
[...]
> To put things in perspective:
>
> int foo()
> {
> return 10;
> }
>
> std::cout << boost::thread(foo).join() << std::endl;
Nah, < using namespace whatever >
int my_operation( int );
class my_fancy_thread : public thread {
public:
class attr : public thread::attr {
public: /*...add some fancy stuff...*/ };
/*...add some fancy stuff...*/ };
// called by thread::attr::new_thread<> function(s)
thread* create_thread_object( const my_fancy_thread::attr& );
// overloads NOOP defaults; called in the context of NEW thread
void on_thread_start( my_fancy_thread* );
void on_thread_termination( my_fancy_thread* );
void thread::main()
{
joinable_thread_ptr< int,my_fancy_thread > pthread =
my_fancy_thread::attr().set_system_contention_scope()
.set_sched_policy( sched::FIFO )
.set_fancy_blabla()
.set_initialy_suspended( true )
.set_daemon( true )
.new_thread( my_operation,
some_magic_number );
/*...*/
pthread->start();
// result is stored in joinable_thread_object< result,thread_type >
// managed by smart thread ptr (thread_ptr<>/joinable_thread_ptr<>)
int* presult = pthread->timedjoin( timeout::relative( 1000 ) );
if ( thread::timedout( presult ) &&
thread::canceled( presult = pthread->cancel().join() ) ) {
cout << "OOPS: timedout and canceled!";
}
else {
cout << "DONE: " << *presult;
}
return 0;
}
regards,
alexander.
-- http://groups.google.com/groups?selm=3E1C9A86.30F0FF41%40web.de
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk