x::run()
      adapts std::thread
      and std::packaged_task to LibCXX's
      reference-counted object model.
      x::run() takes a reference to an object with a
      run() method, which gets invoked in a new
      thread.
    
#include <x/obj.H> #include <x/ref.H> #include <x/threads/run.H> class buttonObj : virtual public x::obj { public: bool run(int x, int y); buttonObj() noexcept; ~buttonObj(); // ... }; typedef x::ref<buttonObj> button; // ... button okButton=button::create(); // ... x::runthread<bool> ret=x::run(okButton, 100, 100); // ... if (ret->terminated()) // ... ret->wait(); bool status=ret->get();
      The first parameter to
      x::run()
      is a reference to an object that itself implements a
      run() method, possibly with parameters.
      x::run takes the reference to an object,
      and invokes the referenced object's run(),
      forwarding to it the remaining arguments to
      x::run().
    
      The referenced object's run() gets invoked in a
      new execution thread, meanwhile x::run()
      returns a
      x::runthread<.
      The arguments to T>run() must be
      copy-constructible.
      x::run() copies the arguments, and
      the thread object's run() gets invoked with the
      copied arguments, which get destroyed after
      run() returns, and just before the new
      execution thread terminates.
    
      x::run() takes care of instantiating
      a new std::thread, and joining the
      thread when it's done. With x::run(), there is
      no concept of joinable and detached threads. The thread started by
      x::run() holds its own reference on the object
      whose run() method got invoked, and releases
      the reference when run() returns.
      The calling thread may keep its reference to the object, for other
      purposes, or all of its references to the object can go out of scope,
      but the new thread's reference keeps the object from getting destroyed
      until run() returns.
    
      When run() returns, an internal cleanup thread
      takes care of joining the terminated thread.
    
	x::run() returns a
	x::runthread<,
	where T>T is the type of the return value
	from the thread object's run().
	Its terminated() method
	returns a boolean that indicates
	whether run() in execution thread started by
	x::run()
	returned and the thread has terminated.
	get() waits for the
	run() method to return, and if
	T is not void,
	returns its return value (the return type of
	run()
	must be, naturally, copy-constructible.
      
	If the execution thread terminated with an exception, rather than
	returning from its run(),
	get() rethrows that exception.
	wait(),
	wait_for(), and
	wait_until() wait until the execution
	thread terminates (either by returning from its
	run(), or by throwing an uncaught exception).
	wait() waits indefinitely, until
	run() returns.
	wait_for() and
	wait_until() take
	a std::chrono::duration or a
	std::chrono::time_point, respectively, setting
	the timeout for the wait.
      
	  All execution threads are expected to terminate before the
	  main application exits by returning from main()
	  or by calling exit().
	  A warning message gets printed to standard error if not, and
	  abort() follows if the remaining
	  threads still do not terminate after thirty seconds.
	
	x::runthread<T> refers to a
	template class that inherits from a non-template
	x::runthreadbaseObj
	class, whose reference type is
	x::runthreadbase.
	It implements just the terminated() and
	wait() methods. In contexts where the return
	value from an object's run() is not required,
	this allows implementation
	of non-templated code that waits for arbitrary execution
	threads to terminate.
      
    pthread_cancel(3) cannot be used in code that uses
    LibCXX. pthread_cancel(3) terminates a thread without
    unwinding the stack. The stack may contain references to
    reference-counted objects, or other objects
    whose destructors contain critical functionality.
  
    Using pthread_cancel(3) will result in memory leaks,
    deadlocks, and other unstable behavior. This is likely to be the case with
    any C++-based process of non-trivial complexity,
    not just LibCXX. The only safe way to forcibly terminate the thread is
    by throwing an exception that unwinds the entire stack frame.
    x::msgdispatcherObj
    provides a convenient message-based thread design pattern which
    supplies a stop() method that sends a message to the
    running thread that causes it to throw an exception and terminate, in an
    orderly manner.
  
run() methods must be copy-constructible
	It's already been mentioned that arguments to execution threads'
	run() methods must have a copy constructor.
      
#include <x/obj.H> #include <x/ref.H> #include <x/threads/run.H> class widget; class rendererObj : virtual public x::obj { public: void run(widget &w); // ... }; void runawidget(const x::ref<renderObj> &r, const widget &w) { x::run(r, w); }
	In this example, the thread object's run()
	method takes a reference to a non-constant widget object. However,
	the argument to x::run() is
	a reference to a constant widget object.
      
	This is because the arguments get copied for the new execution thread.
	The thread object's run() method get invoked
	with the thread's copy of each argument passed to
	x::run().
	The run() method's prototype can specify
	either a constant reference, or a mutable reference to a type, in either
	case it'll get resolved.
      
	This means that although an object may have overloaded
	run() methods, a run()
	that takes a reference to a constant object will never be used if
	there's an overloaded run() method that takes
	a reference to a mutable object (as long as all other parameters are
	the same).
      
template<typename objClass, typename baseClass, typename ...Args> auto start(const x::ref<objClass, baseClass> &thread, Args && ...args) -> typename x::runthread<decltype(thread->run(x::invoke_run_param_helper <Args>()...))> // ...
	As described previously, x::run() returns a
	x::runthread<,
	where T>T gives the return type of
	the object's run(). Sometimes its useful
	to define a template that uses a related type, such as a corresponding
	x::ptr, instead.
	x::invoke_param_helper() helps
	in construing the parameters to a run as if
	they were invoked in the executed thread, given the original
	parameters to x::run().
	Its definition is very short:
      
template<typename param_type> class run_param { public: typedef typename std::decay<param_type>::type &type; }; template<typename param_type> typename run_param<param_type>::type &invoke_run_param_helper();
	Each parameter to x::run() is decay-copied into
	the new execution thread's context, then passed by reference to a
	run() method.
      
	To supply a default thread name for logging
	  purposes, subclass from
	x::runthreadname
	and implement getName(), as follows:
      
#include <x/obj.H> #include <x/runthreadname.H> class myThreadObj : virtual public x::obj, public x::runthreadname { public: // ... void run( ... ); std::string getName() const { return "mythread"; } };
	x::run() invokes
	getName() prior to invoking the thread object's
	run(), to set the thread's name, for logging
	purposes.
      
	By default,
	x::run() has no issues with starting multiple
	concurrent threads, at the same time, using the same class instance.
	To prevent that, subclass
	x::runthreadsingleton:
      
#include <x/obj.H> #include <x/runthreadsingleton.H> class myThreadObj : virtual public x::obj, virtual public x::runthreadsingleton { // ... };
	x::run() now throws an exception if an earlier
	x::run() spawned a thread on the same object,
	and the earlier thread is still running.
	Use virtual public inheritance to subclass
	x::runthreadsingleton, so that a subclass
	that inherits from multiple thread singletons gets a single instance
	of x::runthreadsingleton.
      
auto ret=x::run_lambda([] (const x::netaddr &addr) { x::fd sock=addr->connect(); return sock; }, x::netaddr::create("localhost", "http")); ret->wait(); x::fd val=ret->get();
	x::run_lambda()
	starts a new thread that starts running the lambda given as its
	first parameter, then returns a
	x::runthread<,
	that can be used to wait for the lambda to finish, then retrieve
	the return value from the lambda.
      T>
	x::run() takes care of the hard work of
	using std::thread directly, notably the
	requirement to join the started thread before
	std::thread's destructor gets invoked.
	std::thread is privately owned by a
	x::runthread<
	that gets returned by T>x::run().
	Additionally, the started thread maintains its own reference on the
	thread object, and the x::runthread
	instance.
      
	If all other references to the thread object go out of scope, the
	thread object does not get destroyed before its
	run() returns, since it holds the
	last remaining reference to the thread object. Furthermore, there's
	also an indirect reference on the
	x::runthread, with its private
	std::thread instance, that does not get
	released until after run(), at which point
	its turned over to a cleanup thread.
      
	The first call to x::run() starts a separate
	thread that joins all threads that return from thread objects'
	run()s. A single cleanup thread gets used
	for all x::run()s-started execution threads.
      
	A terminated thread's x::runthread,
	containing its std::thread, gets turned over
	to the cleanup thread, which joins it, sets
	its x::runthread's
	terminated() to true, and makes the
	return value from the thread object's run()
	get()able from the
	x::runthread.
      
	Even if the x::runthread that's returned by
	x::run() gets ignored, an internal reference
	to it gets held by the executing thread. This keeps it from getting
	destroyed until run() returns and the thread
	terminates.
	When that happens, the x::runthread gets
	turned over to the cleanup thread, which joins the terminated
	thread, and then releases the last reference on the
	x::runthread, finally destroying it.
      
	For this reason, the x::runthread could,
	but should not be used as a mcguffin. The cleanup thread is unable
	to continue joining other threads until any destructor callbacks
	return.
      
	fork() invalidates all threads and all thread
	support library classes. They are used extensively by LibCXX, so after
	a fork(), the child processes cannot use any
	LibCXX classes or methods.
      
	fork() has no effect in the parent process.
	All threads remain valid. All thread objects remain valid.
      
	Use x::forkexec
	to safely fork() and exec()
	another process.
      
See also: Chapter 15, Forking other processes.
	The full log message format generated by the
	application logging subsystem
	includes the name of the running thread. This is set by
	getName() method of the thread object passed
	to x::run(),
	if the thread class inherits from
	x::runthreadname,
	or a default name.