DependencyFactory: remove the ability to restart a service explicitly
We don't need this ability and it pushes us into using a central registry. This solution turned out to be problematic when loading dynamic libraries (plug-ins).
This commit is contained in:
parent
dcae33a173
commit
52c83b860b
5 changed files with 9 additions and 74 deletions
|
|
@ -169,31 +169,15 @@ namespace lib {
|
|||
|
||||
/* === Management / Test support interface === */
|
||||
|
||||
/** disable and destroy the actual service instance explicitly.
|
||||
* Next access will re-invoke the factory to create a new instance.
|
||||
* @warning this is a very dangerous operation. Concurrent accesses
|
||||
* might get NULL or even a reference to the old instance,
|
||||
* which, worse still, resides typically in the same memory
|
||||
* location as the new instance. The only way to prevent this
|
||||
* would be to synchronise any \em access (which is expensive)
|
||||
* Thus it is the \em client's duty to ensure there is no such
|
||||
* concurrent access, i.e. all clients of the old instance
|
||||
* should be disabled prior to invoking this function.
|
||||
*/
|
||||
static void
|
||||
shutdown()
|
||||
{
|
||||
SyncLock guard;
|
||||
|
||||
factory.deconfigure (instance);
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
/** temporarily replace the service instance.
|
||||
* The purpose of this operation is to support unit testing.
|
||||
* @param mock reference to an existing service instance (mock).
|
||||
* @return reference to the currently active service instance.
|
||||
* @warning not threadsafe. Same considerations as for \c shutdown() apply
|
||||
* @warning this is a dangerous operation and not threadsafe.
|
||||
* Concurrent accesses might still get the old reference;
|
||||
* the only way to prevent this would be to synchronise
|
||||
* \em any access (which is too expensive).
|
||||
* This feature should only be used for unit tests thusly.
|
||||
* @remark the replacement is not actively managed by the DependencyFactory,
|
||||
* it remains in ownership of the calling client (unit test). Typically
|
||||
* this test will keep the returned original service reference and
|
||||
|
|
|
|||
|
|
@ -74,13 +74,6 @@ namespace lib {
|
|||
__lifecycleCheck();
|
||||
instance().destructionExecutor_.manage (object, customDeleter);
|
||||
}
|
||||
|
||||
static void
|
||||
kill (void* object)
|
||||
{
|
||||
__lifecycleCheck();
|
||||
instance().destructionExecutor_.kill (object);
|
||||
}
|
||||
};
|
||||
|
||||
bool AutoDestructor::shutdownLock = false;
|
||||
|
|
@ -89,19 +82,6 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/** explicitly shut down and destroy a service instance.
|
||||
* This can be used to re-start a service; by default, all
|
||||
* services are created on-demand and stay alive until
|
||||
* application shutdown. But a service deconfigured
|
||||
* through this function is destroyed right away.
|
||||
*/
|
||||
void
|
||||
DependencyFactory::deconfigure (void* existingInstance)
|
||||
{
|
||||
AutoDestructor::kill (existingInstance);
|
||||
}
|
||||
|
||||
|
||||
/** hook to install a deleter function to clean up a service object.
|
||||
* The standard constructor function uses this hook to schedule the
|
||||
* destructor invocation on application shutdown; custom constructors
|
||||
|
|
|
|||
|
|
@ -111,8 +111,6 @@ namespace lib {
|
|||
return ctorFunction_();
|
||||
}
|
||||
|
||||
void deconfigure (void* existingInstance);
|
||||
|
||||
static void scheduleDestruction (void*, KillFun);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -233,19 +233,15 @@ END
|
|||
|
||||
TEST "Dependency injection" DependencyFactory_test <<END
|
||||
out-lit: ctor TargetObj(0) successful
|
||||
out-lit: dtor ~TargetObj(0) successful
|
||||
out-lit: ctor TargetObj(1) successful
|
||||
out-lit: ctor TargetObj(2) successful
|
||||
out-lit: dtor ~TargetObj(2) successful
|
||||
out-lit: ctor TargetObj(3) successful
|
||||
out-lit: ctor TargetObj(4) successful
|
||||
out-lit: ctor TargetObj(5) successful
|
||||
out-lit: dtor ~TargetObj(5) successful
|
||||
out-lit: ctor TargetObj(6) successful
|
||||
out-lit: dtor ~TargetObj(6) successful
|
||||
out-lit: dtor ~TargetObj(4) successful
|
||||
out-lit: dtor ~TargetObj(3) successful
|
||||
out-lit: ctor TargetObj(4) successful
|
||||
out-lit: dtor ~TargetObj(4) successful
|
||||
out-lit: dtor ~TargetObj(2) successful
|
||||
out-lit: dtor ~TargetObj(1) successful
|
||||
out-lit: dtor ~TargetObj(0) successful
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ namespace test{
|
|||
run (Arg)
|
||||
{
|
||||
verify_defaultSingletonCreation();
|
||||
verify_renewal();
|
||||
verify_SubclassCreation();
|
||||
verify_FactoryDefinition_is_sticky();
|
||||
verify_customFactory();
|
||||
|
|
@ -121,26 +120,6 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
verify_renewal()
|
||||
{
|
||||
Depend<Sub> accessor1;
|
||||
Depend<Sub> accessor2;
|
||||
uint id1 = accessor1().instanceID_;
|
||||
CHECK (id1 == accessor2().instanceID_);
|
||||
|
||||
Depend<Sub>::shutdown();
|
||||
|
||||
Sub & o2 = accessor2();
|
||||
uint id2 = accessor2().instanceID_;
|
||||
CHECK (id1 != id2);
|
||||
|
||||
Sub & o1 = accessor1();
|
||||
CHECK (isSameObject (o1, o2));
|
||||
CHECK (id2 == accessor1().instanceID_);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
verify_SubclassCreation()
|
||||
{
|
||||
|
|
@ -164,8 +143,6 @@ namespace test{
|
|||
SubSub& oSub = otherSpecialAccessor();
|
||||
CHECK ( INSTANCEOF (SubSubSub, &oSub));
|
||||
|
||||
Depend<SubSub>::shutdown();
|
||||
|
||||
Depend<SubSub> yetAnotherSpecialAccessor;
|
||||
|
||||
SubSub& yetAnotherInstance = yetAnotherSpecialAccessor();
|
||||
|
|
|
|||
Loading…
Reference in a new issue