3 //=============================================================================
5 * @file Service_Config_Test.cpp
7 * This is a simple test to make sure the ACE Service Configurator
8 * framework is working correctly.
10 * @author David Levine <levine@cs.wustl.edu>
11 * @author Ossama Othman <ossama@uci.edu>
13 //=============================================================================
15 #include "test_config.h"
16 #include "ace/OS_NS_stdio.h"
17 #include "ace/OS_NS_errno.h"
18 #include "ace/OS_NS_Thread.h"
19 #include "ace/Log_Msg.h"
20 #include "ace/Object_Manager.h"
21 #include "ace/Service_Config.h"
22 #include "ace/Service_Object.h"
23 #include "ace/Service_Repository.h"
24 #include "ace/Service_Types.h"
25 #include "ace/Reactor.h"
26 #include "ace/Thread_Manager.h"
29 static const u_int VARIETIES
= 3;
31 static u_int error
= 0;
33 class MyRepository
: public ACE_Service_Repository
38 return service_array_
;
43 * @class Test_Singleton
45 * @brief Test the Singleton
47 * This should be a template class, with singleton instantiations.
48 * But to avoid having to deal with compilers that want template
49 * declarations in separate files, it's just a plain class. The
50 * instance argument differentiates the "singleton" instances. It
51 * also demonstrates the use of the param arg to the cleanup ()
57 static Test_Singleton
*instance (u_short variety
);
62 static u_short current_
;
64 Test_Singleton (u_short variety
);
66 friend class misspelled_verbase_friend_declaration_to_avoid_compiler_warning_with_private_ctor
;
69 u_short
Test_Singleton::current_
= 0;
72 test_singleton_cleanup (void *object
, void *)
74 // We can't reliably use ACE_Log_Msg in a cleanup hook. Yet.
75 /* ACE_DEBUG ((LM_DEBUG, "cleanup %d\n", (u_short) param)); */
77 delete (Test_Singleton
*) object
;
81 Test_Singleton::instance (u_short variety
)
83 static Test_Singleton
*instances
[VARIETIES
] = { 0 };
85 if (instances
[variety
] == 0)
87 ACE_NEW_RETURN (instances
[variety
],
88 Test_Singleton (variety
),
92 ACE_Object_Manager::at_exit (instances
[variety
],
93 test_singleton_cleanup
,
94 reinterpret_cast<void *> (static_cast<size_t> (variety
)),
96 return instances
[variety
];
99 Test_Singleton::Test_Singleton (u_short variety
)
102 if (variety_
!= current_
++)
104 ACE_DEBUG ((LM_ERROR
,
105 ACE_TEXT ("ERROR: instance %u created out of order!\n"),
111 // We can't reliably use ACE_Log_Msg in a destructor that is called by
112 // ACE_Object_Manager. Yet.
114 Test_Singleton::~Test_Singleton ()
116 /* ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Test_Singleton %u dtor\n"), variety_)); */
118 if (variety_
!= --current_
)
120 ACE_OS::fprintf (stderr
,
121 ACE_TEXT ("ERROR: instance %u destroyed out of order!\n"),
123 /* ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ERROR: instance %u destroyed out of order!\n"),
130 testFailedServiceInit (int, ACE_TCHAR
*[])
132 static const ACE_TCHAR
*refuse_svc
=
133 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
134 ACE_TEXT ("dynamic Refuses_Svc Service_Object * ")
135 ACE_TEXT (" Service_Config_DLL:_make_Refuses_Init() \"\"")
137 ACE_TEXT ("<dynamic id=\"Refuses_Svc\" type=\"Service_Object\">")
138 ACE_TEXT (" <initializer init=\"_make_Refuses_Init\" path=\"Service_Config_DLL\" params=\"\"/>")
139 ACE_TEXT ("</dynamic>")
140 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
144 if ((error_count
= ACE_Service_Config::process_directive (refuse_svc
)) != 1)
147 ACE_ERROR ((LM_ERROR
,
148 ACE_TEXT ("Failed init test should have returned 1; ")
149 ACE_TEXT ("returned %d instead\n"),
153 // Try to find the service; it should not be there.
154 ACE_Service_Type
const *svcp
= 0;
155 if (-1 != ACE_Service_Repository::instance ()->find (ACE_TEXT ("Refuses_Svc"),
159 ACE_ERROR ((LM_ERROR
,
160 ACE_TEXT ("Found service repo entry for Refuses_Svc\n")));
161 ACE_Service_Type_Impl
const *svc_impl
= svcp
->type ();
163 ACE_TCHAR
*msgp
= msg
;
164 if (svc_impl
->info (&msgp
, sizeof (msg
) / sizeof (ACE_TCHAR
)) > 0)
165 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Refuses_Svc said: %s\n"), msg
));
168 ACE_DEBUG ((LM_DEBUG
,
169 ACE_TEXT ("Repo reports no Refuses_Svc; correct.\n")));
174 testLoadingServiceConfFileAndProcessNo (int argc
, ACE_TCHAR
*argv
[])
176 u_int error0
= error
;
179 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Starting testLoadingServiceConfFileAndProcessNo\n")));
181 #if defined (ACE_USES_WCHAR)
182 // When using full Unicode support, use the version of the Service
183 // Configurator file appropriate to the platform.
184 // For example, Windows Unicode uses UTF-16.
186 // iconv(1) found on Linux, for example, can
187 // be used to convert between encodings.
189 // Byte ordering is also an issue, so we should be
190 // generating this file on-the-fly from the UTF-8 encoded
191 // file by using functions like iconv(1) or iconv(3).
192 # if defined (ACE_WIN32)
193 const ACE_TCHAR svc_conf
[] =
194 ACE_TEXT ("Service_Config_Test.UTF-16")
195 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
197 const ACE_TCHAR svc_conf
[] =
198 ACE_TEXT ("Service_Config_Test.WCHAR_T")
199 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
200 # endif /* ACE_WIN32 */
202 // ASCII (UTF-8) encoded Service Configurator file.
203 const ACE_TCHAR svc_conf
[] =
204 ACE_TEXT ("Service_Config_Test")
205 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
206 #endif /* ACE_USES_WCHAR */
208 ACE_TCHAR pid_file_name
[MAXPATHLEN
];
209 #if defined (TEST_DIR)
210 ACE_OS::strcpy (pid_file_name
, TEST_DIR
);
211 ACE_OS::strcat (pid_file_name
, ACE_DIRECTORY_SEPARATOR_STR
);
212 ACE_OS::strcat (pid_file_name
, ACE_TEXT ("Service_Config_Test.pid"));
214 ACE_OS::strcpy (pid_file_name
, ACE_TEXT ("Service_Config_Test.pid"));
216 ACE_TCHAR svc_conf_file_name
[MAXPATHLEN
];
217 #if defined (TEST_DIR)
218 ACE_OS::strcpy (svc_conf_file_name
, TEST_DIR
);
219 ACE_OS::strcat (svc_conf_file_name
, ACE_DIRECTORY_SEPARATOR_STR
);
220 ACE_OS::strcat (svc_conf_file_name
, svc_conf
);
222 ACE_OS::strcpy (svc_conf_file_name
, svc_conf
);
225 // Process the Service Configurator directives in this test's Making
226 // sure we have more than one option with an argument, to capture
227 // any errors caused by "reshuffling" of the options.
228 if (new_argv
.add (argv
) == -1
229 || new_argv
.add (ACE_TEXT ("-d")) == -1
230 || new_argv
.add (ACE_TEXT ("-k")) == -1
231 || new_argv
.add (ACE_TEXT ("xxx")) == -1
232 || new_argv
.add (ACE_TEXT ("-p")) == -1
233 || new_argv
.add (pid_file_name
) == -1
234 || new_argv
.add (ACE_TEXT ("-f")) == -1
235 || new_argv
.add (svc_conf_file_name
) == -1)
237 ACE_ERROR ((LM_ERROR
,
238 ACE_TEXT ("line %l %p\n"),
239 ACE_TEXT ("new_argv.add")));
243 // We need this scope to make sure that the destructor for the
244 // <ACE_Service_Config> gets called.
245 ACE_Service_Config daemon
;
247 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Starting daemon using %s\n"), new_argv
.buf ()));
249 if (daemon
.open (new_argv
.argc (), new_argv
.argv ()) == -1 &&
252 ACE_ERROR ((LM_ERROR
,
253 ACE_TEXT ("line %l %p\n"),
254 ACE_TEXT ("daemon.open")));
258 ACE_Time_Value
tv (argc
> 1 ? ACE_OS::atoi (argv
[1]) : 2);
260 if (ACE_Reactor::instance()->run_reactor_event_loop (tv
) == -1)
263 ACE_ERROR ((LM_ERROR
,
264 ACE_TEXT ("line %l %p\n"),
265 ACE_TEXT ("run_reactor_event_loop")));
268 // Wait for all threads to complete.
269 ACE_Thread_Manager::instance ()->wait ();
272 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("testLoadingServiceConfFileAndProcessNo completed successfully\n")));
274 ACE_ERROR ((LM_ERROR
, ACE_TEXT("testLoadingServiceConfFileAndProcessNo test failed\n")));
279 testLoadingServiceConfFile (int argc
, ACE_TCHAR
*argv
[])
283 #if defined (ACE_USES_WCHAR)
284 // When using full Unicode support, use the version of the Service
285 // Configurator file appropriate to the platform.
286 // For example, Windows Unicode uses UTF-16.
288 // iconv(1) found on Linux, for example, can
289 // be used to convert between encodings.
291 // Byte ordering is also an issue, so we should be
292 // generating this file on-the-fly from the UTF-8 encoded
293 // file by using functions like iconv(1) or iconv(3).
294 # if defined (ACE_WIN32)
295 const ACE_TCHAR svc_conf
[] =
296 ACE_TEXT ("Service_Config_Test.UTF-16")
297 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
299 const ACE_TCHAR svc_conf
[] =
300 ACE_TEXT ("Service_Config_Test.WCHAR_T")
301 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
302 # endif /* ACE_WIN32 */
304 // ASCII (UTF-8) encoded Service Configurator file.
305 const ACE_TCHAR svc_conf
[] =
306 ACE_TEXT ("Service_Config_Test")
307 ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT
);
308 #endif /* ACE_USES_WCHAR */
310 // Process the Service Configurator directives in this test's
311 if (new_argv
.add (argv
) == -1
312 || new_argv
.add (ACE_TEXT ("-f")) == -1
313 || new_argv
.add (svc_conf
) == -1)
315 ACE_ERROR ((LM_ERROR
,
316 ACE_TEXT ("line %l %p\n"),
317 ACE_TEXT ("new_argv.add")));
321 // We need this scope to make sure that the destructor for the
322 // <ACE_Service_Config> gets called.
323 ACE_Service_Config daemon
;
325 if (daemon
.open (new_argv
.argc (), new_argv
.argv ()) == -1)
328 ACE_DEBUG ((LM_WARNING
,
329 ACE_TEXT ("ACE_Service_Config::open: %p\n"),
332 ACE_ERROR ((LM_ERROR
,
333 ACE_TEXT ("ACE_Service_Config::open: %p\n"),
334 ACE_TEXT ("error")));
337 ACE_Time_Value
tv (argc
> 1 ? ACE_OS::atoi (argv
[1]) : 2);
339 if (ACE_Reactor::instance()->run_reactor_event_loop (tv
) == -1)
342 ACE_ERROR ((LM_ERROR
,
343 ACE_TEXT ("line %l %p\n"),
344 ACE_TEXT ("run_reactor_event_loop")));
347 // Wait for all threads to complete.
348 ACE_Thread_Manager::instance ()->wait ();
352 // Loading and unloading the ACE logger service should not smash singletons.
354 testUnloadingACELoggingStrategy (int, ACE_TCHAR
*[])
356 static const ACE_TCHAR
*load_logger
=
357 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
358 ACE_TEXT ("dynamic Logger Service_Object * ")
359 ACE_TEXT (" ACE:_make_ACE_Logging_Strategy() \"\"")
361 ACE_TEXT ("<dynamic id=\"Logger\" type=\"Service_Object\">")
362 ACE_TEXT (" <initializer init=\"_make_ACE_Logging_Strategy\" ")
363 ACE_TEXT (" path=\"ACE\" params=\"\"/>")
364 ACE_TEXT ("</dynamic>")
365 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
368 static const ACE_TCHAR
*unload_logger
=
369 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
370 ACE_TEXT ("remove Logger")
372 ACE_TEXT ("<remove id=\"Logger\" />");
373 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
376 ACE_Reactor
*r1
= ACE_Reactor::instance();
378 // Ensure no errors are logged while searching for a valid ACE lib name;
379 // these skew the scoreboard results.
380 u_long mask
= ACE_LOG_MSG
->priority_mask (ACE_Log_Msg::PROCESS
);
381 ACE_LOG_MSG
->priority_mask (mask
& ~LM_ERROR
, ACE_Log_Msg::PROCESS
);
382 ACE_DEBUG ((LM_DEBUG
, "Was %x, now %x\n", mask
, mask
& ~LM_ERROR
));
383 int error_count
= ACE_Service_Config::process_directive (load_logger
);
384 ACE_LOG_MSG
->priority_mask (mask
);
385 if (error_count
!= 0)
388 ACE_ERROR ((LM_ERROR
,
389 ACE_TEXT ("Load ACE Logger should have returned 0; ")
390 ACE_TEXT ("returned %d instead\n"),
393 ACE_Service_Config::process_directive (unload_logger
);
395 ACE_Reactor
*r2
= ACE_Reactor::instance ();
397 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Reactor before %@, after %@\n"), r1
, r2
));
401 // @brief The size of a repository is unlimited and can be exceeded
403 testLimits (int , ACE_TCHAR
*[])
405 static const ACE_TCHAR
*svc_desc1
=
406 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
407 ACE_TEXT ("dynamic Test_Object_1_More Service_Object * ")
408 ACE_TEXT (" Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_1_More\"")
410 ACE_TEXT ("<dynamic id=\"Test_Object_1_More\" type=\"Service_Object\">")
411 ACE_TEXT (" <initializer init=\"_make_Service_Config_DLL\" path=\"Service_Config_DLL\" params=\"Test_Object_1_More\"/>")
412 ACE_TEXT ("</dynamic>")
413 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
416 static const ACE_TCHAR
*svc_desc2
=
417 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
418 ACE_TEXT ("dynamic Test_Object_2_More Service_Object * ")
419 ACE_TEXT (" Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_2_More\"")
421 ACE_TEXT ("<dynamic id=\"Test_Object_2_More\" type=\"Service_Object\">")
422 ACE_TEXT (" <initializer init=\"_make_Service_Config_DLL\" path=\"Service_Config_DLL\" params=\"Test_Object_2_More\"/>")
423 ACE_TEXT ("</dynamic>")
424 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
427 u_int error0
= error
;
429 // Ensure enough room for one in a own, the repository can extend
430 ACE_Service_Gestalt
one (1, true);
433 // We cant simply rely on the fact that insertion fails, because it
434 // is typical to have no easy way of getting detailed error
435 // information from a parser.
436 one
.process_directive (svc_desc1
);
437 one
.process_directive (svc_desc2
);
439 if (-1 == one
.find (ACE_TEXT ("Test_Object_1_More"), 0, 0))
442 ACE_ERROR ((LM_ERROR
, ACE_TEXT("Expected to have registered the first service\n")));
445 if (-1 == one
.find (ACE_TEXT ("Test_Object_2_More"), 0, 0))
448 ACE_ERROR ((LM_ERROR
, ACE_TEXT("Expected to have registered the second service\n")));
452 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, ace_mon
, one
.current_service_repository ()->lock ());
454 ACE_Service_Repository_Iterator
sri (*one
.current_service_repository (), 0);
457 for (const ACE_Service_Type
*sr
;
461 if (index
== 0 && ACE_OS::strcmp (sr
->name(), ACE_TEXT ("Test_Object_1_More")) != 0)
464 ACE_ERROR ((LM_ERROR
, ACE_TEXT("Service 1 is wrong\n")));
466 if (index
== 1 && ACE_OS::strcmp (sr
->name(), ACE_TEXT ("Test_Object_2_More")) != 0)
469 ACE_ERROR ((LM_ERROR
, ACE_TEXT("Service 2 is wrong\n")));
476 one
.current_service_repository ()->close();
478 if (one
.current_service_repository ()->current_size () != 0)
481 ACE_ERROR ((LM_ERROR
, ACE_TEXT("Size of repository should be 0\n")));
485 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Limits test completed successfully\n")));
487 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Limits test failed\n")));
491 testrepository (int, ACE_TCHAR
*[])
493 MyRepository repository
;
495 ACE_Service_Type
s0 (ACE_TEXT ("0"), 0, handle
, false);
496 ACE_Service_Type
s1 (ACE_TEXT ("1"), 0, handle
, false);
497 ACE_Service_Type
s2 (ACE_TEXT ("2"), 0, handle
, false);
498 ACE_Service_Type
s3 (ACE_TEXT ("3"), 0, handle
, false);
499 ACE_Service_Type
* result
= 0;
500 repository
.insert (&s0
);
501 if (repository
.current_size () != 1)
504 ACE_ERROR ((LM_ERROR
,
505 ACE_TEXT ("Repository was wrong size %d\n"),
506 repository
.current_size ()));
508 repository
.insert (&s1
);
509 if (repository
.current_size () != 2)
512 ACE_ERROR ((LM_ERROR
,
513 ACE_TEXT ("Repository was wrong size %d\n"),
514 repository
.current_size ()));
516 repository
.insert (&s2
);
517 if (repository
.current_size () != 3)
520 ACE_ERROR ((LM_ERROR
,
521 ACE_TEXT ("Repository was wrong size %d\n"),
522 repository
.current_size ()));
524 if (repository
.remove (ACE_TEXT ("1"), &result
) != 0)
527 ACE_ERROR ((LM_ERROR
,
528 ACE_TEXT ("Remove failed\n")));
530 if (repository
.current_size () != 3)
533 ACE_ERROR ((LM_ERROR
,
534 ACE_TEXT ("Repository was wrong size %d\n"),
535 repository
.current_size ()));
537 if (repository
.array ()[1] != 0)
540 ACE_ERROR ((LM_ERROR
,
541 ACE_TEXT ("Element 1 not zero\n"),
542 repository
.current_size ()));
544 repository
.insert (&s3
);
545 if (repository
.current_size () != 4)
548 ACE_ERROR ((LM_ERROR
,
549 ACE_TEXT ("Repository was wrong size %d\n"),
550 repository
.current_size ()));
552 repository
.remove (ACE_TEXT ("0"), &result
);
553 if (repository
.remove (ACE_TEXT ("1"), &result
) != -1)
556 ACE_ERROR ((LM_ERROR
,
557 ACE_TEXT ("Double remove didn't return -1\n")));
559 repository
.remove (ACE_TEXT ("2"), &result
);
560 repository
.remove (ACE_TEXT ("3"), &result
);
561 if (repository
.current_size () != 4)
564 ACE_ERROR ((LM_ERROR
,
565 ACE_TEXT ("Repository was wrong size %d\n"),
566 repository
.current_size ()));
569 if (repository
.current_size () != 0)
572 ACE_ERROR ((LM_ERROR
,
573 ACE_TEXT ("Repository was wrong size %d\n"),
574 repository
.current_size ()));
580 testOrderlyInstantiation (int , ACE_TCHAR
*[])
582 for (u_int i
= 0; i
< VARIETIES
; ++i
)
584 Test_Singleton
*s
= Test_Singleton::instance (i
);
589 ACE_ERROR ((LM_ERROR
,
590 ACE_TEXT ("instance () allocate failed!\n")));
595 // This test verifies that services loaded by a normal ACE startup can be
596 // located from a thread spawned outside of ACE's control.
598 // To do this, we need a native thread entry and, thus, it needs special care
599 // for each platform type. Feel free to add more platforms as needed here and
600 // in main() where the test is called.
601 #if defined (ACE_HAS_WTHREADS) || defined (ACE_HAS_PTHREADS)
602 # if defined (ACE_HAS_WTHREADS)
603 extern "C" unsigned int __stdcall
605 extern "C" ACE_THR_FUNC_RETURN
607 nonacethreadentry (void *args
)
609 ACE_Log_Msg::inherit_hook (0, *(ACE_OS_Log_Msg_Attributes
*)args
);
611 if (ACE_Service_Config::instance()->find(ACE_TEXT("Test_Object_1_Thr")) != 0)
613 ACE_ERROR ((LM_ERROR
,
614 ACE_TEXT ("In thr %t cannot find Test_Object_1_Thr ")
615 ACE_TEXT ("via ACE_Service_Config\n")));
619 ACE_DEBUG ((LM_DEBUG
,
620 ACE_TEXT ("In thr %t, located Test_Object_1_Thr ")
621 ACE_TEXT ("via ACE_Service_Config\n")));
623 if (0 != ACE_Service_Repository::instance()->find
624 (ACE_TEXT("Test_Object_1_Thr")))
626 ACE_ERROR ((LM_ERROR
,
627 ACE_TEXT ("In thr %t cannot find Test_Object_1_Thr ")
628 ACE_TEXT ("via ACE_Service_Repository\n")));
632 ACE_DEBUG ((LM_DEBUG
,
633 ACE_TEXT ("In thr %t, located Test_Object_1_Thr ")
634 ACE_TEXT ("via ACE_Service_Repository\n")));
642 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Beginning non-ACE thread lookup test\n")));
644 static const ACE_TCHAR
*svc_desc
=
645 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
646 ACE_TEXT ("dynamic Test_Object_1_Thr Service_Object * ")
647 ACE_TEXT (" Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_1_Thr\"")
649 ACE_TEXT ("<dynamic id=\"Test_Object_1_Thr\" type=\"Service_Object\">")
650 ACE_TEXT (" <initializer init=\"_make_Service_Config_DLL\" path=\"Service_Config_DLL\" params=\"Test_Object_1_Thr\"/>")
651 ACE_TEXT ("</dynamic>")
652 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
655 static const ACE_TCHAR
*svc_remove
=
656 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
657 ACE_TEXT ("remove Test_Object_1_Thr")
659 ACE_TEXT ("<remove id=\"Test_Object_1_Thr\"/>")
660 ACE_TEXT ("</remove>")
661 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
664 if (-1 == ACE_Service_Config::process_directive (svc_desc
))
666 ACE_ERROR ((LM_ERROR
,
668 ACE_TEXT ("Error loading service")));
673 // Allow the spawned thread to contribute to the logging output.
674 ACE_OS_Log_Msg_Attributes log_msg_attrs
;
675 ACE_Log_Msg::init_hook (log_msg_attrs
);
677 u_int errors_before
= error
;
679 #if defined (ACE_HAS_WTHREADS)
680 HANDLE thr_h
= (HANDLE
)_beginthreadex (0,
688 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("_beginthreadex")));
693 WaitForSingleObject (thr_h
, INFINITE
);
696 #elif defined (ACE_HAS_PTHREADS)
698 int status
= pthread_create (&thr_id
, 0, nonacethreadentry
, &log_msg_attrs
);
702 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("pthread_create")));
707 pthread_join (thr_id
, 0);
711 if (error
!= errors_before
) // The test failed; see if we can still see it
713 if (0 != ACE_Service_Config::instance()->find (ACE_TEXT ("Test_Object_1_Thr")))
715 ACE_ERROR ((LM_ERROR
,
716 ACE_TEXT ("Main thr %t cannot find Test_Object_1_Thr\n")));
720 ACE_DEBUG ((LM_DEBUG
,
721 ACE_TEXT ("Main thr %t DOES find Test_Object_1_Thr\n")));
724 if (-1 == ACE_Service_Config::process_directive (svc_remove
))
726 ACE_ERROR ((LM_ERROR
,
728 ACE_TEXT ("Error removing service")));
733 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Non-ACE thread lookup test completed\n")));
736 #endif /* ACE_HAS_WTHREADS || ACE_HAS_PTHREADS */
739 run_main (int argc
, ACE_TCHAR
*argv
[])
741 ACE_START_TEST (ACE_TEXT ("Service_Config_Test"));
743 testOrderlyInstantiation (argc
, argv
);
744 testFailedServiceInit (argc
, argv
);
745 testLoadingServiceConfFile (argc
, argv
);
746 testLoadingServiceConfFileAndProcessNo (argc
, argv
);
747 testUnloadingACELoggingStrategy (argc
, argv
);
748 testLimits (argc
, argv
);
749 testrepository (argc
, argv
);
750 #if defined (ACE_HAS_WTHREADS) || defined (ACE_HAS_PTHREADS)
751 unsigned int n_threads
= 64;
752 #if defined (ACE_DEFAULT_THREAD_KEYS)
753 n_threads
= 2 * ACE_DEFAULT_THREAD_KEYS
;
755 // Test with a large amount of threads to determine whether
756 // TSS works correctly with non ACE threads
757 for (unsigned int i
= 0 ; i
< n_threads
; i
++)