1 // ============================================================================
7 // This program tests both the ACE_Framework_Compondent and ACE_Repository.
8 // Since Framework Components are singletons that can live in dlls loaded
9 // via the Service Configurator framework, this test uses that framework
10 // to load services from a dll that has a singleton based on ACE_DLL_Singleton.
11 // When the dll is finally ready to be unloaded, the singleton will be
12 // automatically cleaned up just-in-time.
15 // Don Hinton <dhinton@ieee.org>
17 // ============================================================================
19 #include "test_config.h"
20 #include "ace/Service_Config.h"
22 #include "ace/DLL_Manager.h"
24 // Define a few macros--because they're so much fun, and keep the
25 // code below a little cleaner...
26 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
28 # define ADD_SERVICE(X) \
29 ACE_TEXT ("dynamic Server_") ACE_TEXT(#X) \
30 ACE_TEXT (" Service_Object * ") \
31 ACE_TEXT ("Framework_Component_DLL:_make_Server_") ACE_TEXT(#X) \
34 # define REMOVE_SERVICE(X) \
35 ACE_TEXT ("remove Server_") ACE_TEXT(#X)
37 #else /* ACE_USES_CLASSIC_SVC_CONF */
39 # define ADD_SERVICE(X) \
40 ACE_TEXT ("<?xml version='1.0'?> <dynamic id='Server_") ACE_TEXT(#X) ACE_TEXT("' ") \
41 ACE_TEXT ("type='service_object'> <initializer init='_make_Server_") ACE_TEXT(#X) ACE_TEXT("' ") \
42 ACE_TEXT ("path='Framework_Component_DLL' params=''/> </dynamic>")
44 # define REMOVE_SERVICE(X) \
45 ACE_TEXT ( "<?xml version='1.0'?> <remove id='Server_") ACE_TEXT(#X) \
46 ACE_TEXT("'> </remove>")
48 #endif /* ACE_USES_CLASSIC_SVC_CONF */
51 run_test (u_long unload_mask
= 0)
53 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Running test with mask = %s|%s\n"),
54 ACE_BIT_ENABLED(unload_mask
, ACE_DLL_UNLOAD_POLICY_PER_DLL
) == 0
55 ? ACE_TEXT ("PER_PROCESS") : ACE_TEXT ("PER_DLL"),
56 ACE_BIT_ENABLED(unload_mask
, ACE_DLL_UNLOAD_POLICY_LAZY
) == 0
57 ? ACE_TEXT ("EAGER") : ACE_TEXT ("LAZY")));
59 ACE_DLL_Manager::instance ()->unload_policy (unload_mask
);
61 // Now, let the ACE Service Configurator framework load our service from a
62 // dll, which contains a singleton.
63 ACE_Service_Config::open (ACE_TEXT ("Framework_Component_Test"),
64 ACE_DEFAULT_LOGGER_KEY
,
68 ACE_Service_Config::process_directive (ADD_SERVICE(1));
70 // And unload the first one, could unload the dll.
71 ACE_Service_Config::process_directive (REMOVE_SERVICE(1));
73 // Now readd server 1.
74 ACE_Service_Config::process_directive (ADD_SERVICE(1));
76 // And load another service from the same library.
77 ACE_Service_Config::process_directive (ADD_SERVICE(2));
79 // Unload the first one again, should *not* unload the dll this time.
80 ACE_Service_Config::process_directive (REMOVE_SERVICE(1));
82 // And unload the second service. Since the ACE_DLL_Handle will no longer
83 // have any references, the ACE_DLL_Manager will apply it's current unloading
84 // strategy and either call ACE_OS::dlclose() immediately, schedule a timeout
85 // the the reactor to call dlclose() some time in the future, or keep the
86 // dll loaded until program termination.
87 ACE_Service_Config::process_directive (REMOVE_SERVICE(2));
89 // Force unloading so we'll be ready for the next test.
90 ACE_DLL_Manager::instance ()->unload_policy (ACE_DLL_UNLOAD_POLICY_DEFAULT
);
92 ACE_Service_Config::close ();
97 run_main (int, ACE_TCHAR
*[])
99 ACE_START_TEST (ACE_TEXT("Framework_Component_Test"));
103 // Use defaults, i.e., per process, eager unloading.
104 retval
+= run_test (ACE_DLL_UNLOAD_POLICY_DEFAULT
);
106 // Per process, lazy unloading
107 retval
+= run_test (ACE_DLL_UNLOAD_POLICY_LAZY
);
109 // Per dll, eager unloading
110 retval
+= run_test (ACE_DLL_UNLOAD_POLICY_PER_DLL
);
112 // Per dll, lazy unloading.
113 retval
+= run_test (ACE_DLL_UNLOAD_POLICY_PER_DLL
| ACE_DLL_UNLOAD_POLICY_LAZY
);
116 return retval
== 0 ? 0 : -1;