|
Boost : |
From: Michael Goldshteyn (mgoldshteyn_at_[hidden])
Date: 2005-07-28 15:47:41
What is:
namespace boost
{
const class
{
???
Mike
"Jason Hise" <chaos_at_[hidden]> wrote in message
news:42E93F43.4040204_at_ezequal.com...
> This message is an in depth description of my current design plan for a
> new singleton library, which I hope to complete and schedule for review
> by boost in the coming year. I would appreciate any comments,
> questions, or suggestions regarding this plan before I begin work on the
> code. Specifically, I would like to know if there are any important
> issues that this design fails to address, or difficulties with the
> interface that would turn away potential users.
>
> (My old singleton library, which was not accepted by boost, is available
> at http://tinyurl.com/6qvrd. It was rejected primarily because it
> failed to adequately address concerns related to multi threading and
> dlls.)
>
> Thus far, my high level design plan looks like this:
>
> The creator_policy defines fundamental pointer, const_pointer, and
> reference types. These hold references to a creator policy instance
> which maintains the singleton internally, so that the pointer types can
> always see and access the state of the single instance. This way,
> pointers to the singleton instance are not invalidated when the state of
> the singleton changes. The creator_policy defines create, replace, and
> destroy methods, as well as methods to generate instances of the various
> pointer types. Create only creates the instance if it does not already
> exist, destroy only destroys the instance if it does exist, and replace
> makes sure any existing instance is destroyed before attempting
> creation. Thus far, I hope to support the following creators:
>
> --------------------------------------------------------------------------------
>
> in_place_creator
> creates/destroys inside an aligned_storage POD
>
> interface:
>
> create ( [ctor params] );
> replace ( [ctor params] );
> destroy ( );
>
> pros: no memory allocation/deallocation ever required
> constructor params can be easily specified
>
> cons: automatic creation, when it occurs, always uses the default
> constructor
> singleton cannot be created as a derived type
>
> useful for simple, user defined singleton classes
>
> --------------------------------------------------------------------------------
>
> source_sink_creator
> owns fixed source and sink functors, specified with template parameters
>
> interface:
>
> create ( );
> replace ( );
> destroy ( );
>
> pros: source can return a derived type
> automatic creation uses source rather than default construction
>
> cons: source and sink cannot be set or changed at runtime
> constructor arguments cannot be specified by calling code
>
> useful for singleton types provided by untouchable code, which may
> require calling special functions to get pointers to instances
>
> --------------------------------------------------------------------------------
>
> dynamic_source_sink_creator
> owns dynamic source and sink functors
>
> interface:
>
> create ( [source[, sink]] );
> replace ( [source[, sink]] );
> destroy ( [source[, sink]] );
>
> pros: source can return a derived type
> automatic creation uses source rather than default construction
> source and sink can optionally be changed at run time
> source and sink can change functor types when they are set
> (example: from function pointer to lambda expression)
>
> cons: specifying constructor parameters to pass is non-trivial
> dynamic memory allocation and virtual functions must be used to
> store the functors
> in order to allow for different functor types at runtime, thus
> creation is more
> expensive and can potentially fail
>
> useful for a singleton which needs to take the forms of unspecified
> derived types
> and is frequently destroyed and created via some type of factory
>
> --------------------------------------------------------------------------------
>
> The lifetime_policy owns and wraps the creator policy, and provides
> pointer and reference types which wrap those belonging to the creator.
> It also provides functions to generate instances of the various pointer
> types, and provides a function to access the creator_policy instance.
> The unmanaged lifetime simply typedefs the underlying pointer and
> reference types, and thus results in no overhead. The
> longevity_lifetime and lifo_lifetime behave similarly, but handle
> scheduling of automated destruction when any of the pointer generation
> methods are called. The dependency_lifetime will wrap the internal
> pointer types to perform reference counting (the reference count itself
> will be stored in the lifetime_policy instance). The timeout_lifetime
> will manage a separate thread that releases the instance when it
> finishes counting down. It will also wrap the internal pointer types to
> reset the timer when a pointer is dereferenced, and reset and lock the
> timer while any references exist.
>
> The threading_policy owns and serializes access to the lifetime_policy.
> It also has a function to get access to the lifetime_policy instance,
> and provides pointer, const_pointer, and reference types which wrap and
> forward to the lifetime's corresponding types. For the single_threaded
> policy, these pointer types are simply typedefs of the lifetime's
> pointer types, resulting in no overhead, and the function through which
> the lifetime_policy instance is accessed just returns a raw pointer to
> it. For the multi_threaded policy, pointer types perform locking before
> forwarding to lifetime pointer types, and the reference type acts as a
> lock throughout it's existence. The mutex is stored inside the
> threading_policy instance. The function which returns a pointer to the
> lifetime_policy instance returns a smart pointer which serializes access.
>
> A storage_policy determines how instances of the threading_policy are
> stored (and because these instances contain instances of the other
> policies, this indirectly controls how all of the policy instances are
> stored). static_storage stores policy instances directly as global
> variables, which is fine for singletons that are not required to have a
> specific lifetime with regard to other singletons. These global
> variables will be set up in such a way that it will be guaranteed that
> any automatic destruction takes place before the policy bundle is
> destroyed. group_storage allows multiple singletons to have their
> policies stored in a master group. No policies in this group are
> destroyed until all automated destruction that will be performed by any
> members of the group has completed. This way, if destructors of some of
> the singletons in this group trigger re-creation of other singletons in
> the same group, the policies needed to recreate the singletons are
> guaranteed to still exist. dll_storage requires linking with
> singleton.dll, and stores instances in a special exported manager
> singleton to ensure unique singleton instances across dll boundaries.
> All policy instances of this type are guaranteed to be destroyed only
> after all automated destruction has taken place.
>
> A singleton class exists, which takes a singleton type and a name tag as
> template parameters. The name will have a default type called
> 'unnamed'. This name parameter enables using multiple singleton
> instances of the same type. Policies are traits of the name specified,
> so using the default name 'unnamed' results in using the default
> policies. Policies can be specified by declaring a name as an undefined
> struct, and then specializing the desired policy traits for that name.
>
> The singleton class contains three pointer types, which wrap those of
> the threading policy. These are strong_pointer, lazy_pointer, and
> weak_pointer. strong_pointer attempts automatic creation of the
> singleton instance if it does not exist when the pointer is first
> created, and also attempts automatic creation if needed any time it is
> dereferenced. lazy_pointer only attempts automatic creation when
> dereferenced, and weak_pointer will never create the instance
> automatically. For the lifo_lifetime, a strong_pointer can be used to
> specify a dependency of some singleton B on some singleton A by having B
> own a strong_pointer to A. This will ensure that A is created before B
> and destroyed after B.
>
> Const versions of these three pointer types will also exist. Creation,
> destruction, and non-const member functions will not be allowed to be
> called through these const pointer types. A single reference type will
> exist which will be the result of dereferencing any pointer type via the
> unary * operator. const_pointers return const qualified references.
> Pointers only perform temporary locking (if the threading policy
> supports locking) when a member function is called via the -> operator
> or when a create or destroy operation is invoked. References lock the
> singleton throughout their entire lifetime, and thus can be used to make
> a series of operations on the singleton instance atomic. A reference
> provides an implicit conversion to a raw reference of the singleton's
> type (which comes back const if the reference is const). Create and
> destroy can only be called on non-const references.
>
> Typical code will access a singleton instance by creating one of the
> above pointer types and calling member functions through it via the ->
> operator. Ex:
>
> singleton < MyType, SomeName >::lazy_pointer ptr;
> ptr->DoSomething ( );
>
> --------------------------------------------------------------------------------
>
> I plan to sneak an improved version of the null developed by Scott
> Meyers in with this code in a header called boost/null.hpp, and use it
> in the singleton's implementation. It will be defined as follows:
>
> namespace boost
> {
> const class
> {
> private:
> void operator & ( ) const;
>
> public:
> #ifndef BOOST_NO_MEMBER_TEMPLATES
>
> // provide conversion to any pointer type
> template < typename Class, typename Type >
> operator Type Class::* ( ) const { return 0; }
>
> template < typename Type >
> operator Type * ( ) const { return 0; }
>
> #else
>
> //provide conversion to int if member templates are not supported
> operator int ( ) const { return 0; }
>
> #endif//BOOST_NO_MEMBER_TEMPLATES
>
> } null;
> }
>
> #undef NULL
> #define NULL (::boost::null)
>
> --------------------------------------------------------------------------------
>
> Any and all comments or suggestions on this plan are welcomed.
> Potential problems are much easier to address at design time than after
> the code is written.
>
> -Jason
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk