diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-04-23 04:26:25 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-04-23 04:26:25 +0000 |
commit | 35d953eb3aef94113f388d8079688e96a4a327aa (patch) | |
tree | 18c6cc58e4961fdf9908868a8dd4647126a88d02 | |
parent | 296af34a9b459fa56355903b15216f09e6f4897b (diff) | |
download | ATCD-35d953eb3aef94113f388d8079688e96a4a327aa.tar.gz |
*** empty log message ***
-rw-r--r-- | ChangeLog-97a | 84 | ||||
-rw-r--r-- | ace/Hash_Map_Manager.cpp | 14 | ||||
-rw-r--r-- | ace/Hash_Map_Manager.h | 6 | ||||
-rw-r--r-- | ace/LSOCK.h | 6 | ||||
-rw-r--r-- | ace/Local_Name_Space.h | 2 | ||||
-rw-r--r-- | ace/README | 1 | ||||
-rw-r--r-- | ace/Strategies_T.cpp | 82 | ||||
-rw-r--r-- | ace/Strategies_T.h | 56 | ||||
-rw-r--r-- | ace/config-sunos5.4-centerline-2.x.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.4-g++.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.4-sunc++-4.x-orbix.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.4-sunc++-4.x.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.5-g++.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.5-sunc++-4.1.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.5-sunc++-4.x-orbix.h | 2 | ||||
-rw-r--r-- | ace/config-sunos5.5-sunc++-4.x.h | 2 | ||||
-rw-r--r-- | tests/Map_Manager_Test.cpp | 11 | ||||
-rw-r--r-- | tests/Pipe_Test.cpp | 1 | ||||
-rw-r--r-- | tests/Process_Strategy_Test.cpp | 331 | ||||
-rw-r--r-- | tests/test_config.h | 4 |
20 files changed, 531 insertions, 83 deletions
diff --git a/ChangeLog-97a b/ChangeLog-97a index 49d4a89eacb..58201de1b09 100644 --- a/ChangeLog-97a +++ b/ChangeLog-97a @@ -1,3 +1,74 @@ +Tue Apr 22 20:17:00 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * tests/Process_Strategy_Test.cpp: Added new test code that + exercises the ACE_Process_Strategy, ACE_Thread_Strategy, and + ACE_Reactive_Strategy classes. + + * ace/Strategies_T: Added a new class called + ACE_Reactive_Strategy, which inherits from + ACE_Concurrency_Strategy and registers new Svc_Handlers with the + Reactor. + + * ace/Strategies_T.cpp (ACE_Thread_Strategy): Added a check for + failed open() methods and call ACE_ERROR. + + * tests/Map_Manager_Test.cpp: Added a template specialization for + the ACE_Hash_Map_Manager::hash() method, which is enabled if the + compiler supports template specializations. + + * ace/Hash_Map_Manager.h (pool): Moved the ext_id.hash() call into + a separate method so that we can perform template specialization + of it more easily. + + * ace/README: Added a new #define called + ACE_HAS_TEMPLATE_SPECIALIZATION so that we can work around funky + compilers that don't support this advanced template feature. + + * ace: Added Nanbor Wang's port to FreeBSD. The port is done + at FreeBSD 3.0-current as of 2/9/97, which is the + latest stable system before Lite2 merge. Since the merge is + current under testing and changes are introduced in a daily + basis, I don't recommend using -current after the date. You + can specified the date in your "supfile", run CVSup to get the entire + source tree and do a 'make world' to update (or reverse) your + system. + + Pthread library is provided by John Birrell. There is a + bug fix at mid April so you may want to CVSup the latest libc_r + library and re-make the pthreaded library. + + Notice that under FreeBSD, the environment variable + LD_LIBRARY_PATH has no effect at all (for stricter security reason + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + (?)) Also, a shared library must be name as lib<name>.so.<version + number> (e.g. libACE.4.1.0). Therefore, if you want to take + advantage of shared library (libACE.so), you'll need to either + + 1. move libACE.so to /usr/local/lib, rename it as libACE.so.4.1.5 + then, you'll be able to use it after reboot (or, use 'ldconfig + -m' to "merge" it into current cache immediately, or + 2. rename it as libACE.so.4.1.5 and do an 'ldconfig -m + $WRAPPER_ROOT/ace' to put it into cache. You may want to put + it into <rc> file. + + No matter which scheme you use, you'll need to have root privilege + to do it (invoke the shared object into system.) + I would recommend adding a post-compile hook in the Makefile so we + FreeBSDers can rename the shared library to it's proper name with + correct major and minor version number attached. (which is a + trick BSD library makefiles use.) + + * examples/OS/Process/process.cpp (main): Replaced the use of + "/bin/cat" with "cat" since we are now using execvp(). Thanks + to Nanbor Wang <nw1@cs.wustl.edu> for reporting this. + + * ace/Process.cpp (start): Changed the use of execv() to execvp() + in order to avoid having to pass in the full pathname. + + * ace/OS.i (sigwait): Added an #ifdef for FreeBSD so that we + return ACE_NOTSUP_RETURN(-1) for ACE_OS::sigwait(). Thanks to + Nanbor Wang <nw1@cs.wustl.edu> for reporting this. + Tue Apr 22 17:46:30 1997 <harrison@samba.cs.wustl.edu> * Process.cpp (start): We must pass in 0 instead of "" to @@ -45,19 +116,6 @@ Tue Apr 22 01:38:14 1997 <irfan@TWOSTEP> * examples/Reactor/Proactor/test_proactor.{mdp,mak}: Added new example. -Tue Apr 22 00:21:03 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * examples/OS/Process/process.cpp (main): Replaced the use of - "/bin/cat" with "cat" since we are now using execvp(). Thanks - to Nanbor Wang <nw1@cs.wustl.edu> for reporting this. - - * ace/Process.cpp (start): Changed the use of execv() to execvp() - in order to avoid having to pass in the full pathname. - - * ace/OS.i (sigwait): Added an #ifdef for FreeBSD so that we - return ACE_NOTSUP_RETURN(-1) for ACE_OS::sigwait(). Thanks to - Nanbor Wang <nw1@cs.wustl.edu> for reporting this. - Mon Apr 21 18:14:32 1997 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> * ace/config-win32-common.h: Added checks around _AFXDLL before diff --git a/ace/Hash_Map_Manager.cpp b/ace/Hash_Map_Manager.cpp index 15d86d8a95c..2b4986ec44d 100644 --- a/ace/Hash_Map_Manager.cpp +++ b/ace/Hash_Map_Manager.cpp @@ -191,11 +191,17 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::total_size (void) return this->total_size_; } +template <class EXT_ID, class INT_ID, class LOCK> size_t +ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::hash (const EXT_ID &ext_id) +{ + return ext_id.hash (); +} + template <class EXT_ID, class INT_ID, class LOCK> int ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::bind_i (const EXT_ID &ext_id, const INT_ID &int_id) { - size_t loc = ext_id.hash () % this->total_size_; + size_t loc = this->hash (ext_id) % this->total_size_; ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc]; @@ -235,7 +241,7 @@ template <class EXT_ID, class INT_ID, class LOCK> int ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::trybind_i (const EXT_ID &ext_id, INT_ID &int_id) { - size_t loc = ext_id.hash () % this->total_size_; + size_t loc = this->hash (ext_id) % this->total_size_; ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc]; @@ -279,7 +285,7 @@ template <class EXT_ID, class INT_ID, class LOCK> int ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind_i (const EXT_ID &ext_id, INT_ID &int_id) { - size_t loc = ext_id.hash () % this->total_size_; + size_t loc = this->hash (ext_id) % this->total_size_; ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc]; ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev = 0; @@ -334,7 +340,7 @@ template <class EXT_ID, class INT_ID, class LOCK> int ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_find (const EXT_ID &ext_id, ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry) { - size_t loc = ext_id.hash () % total_size_; + size_t loc = this->hash (ext_id) % this->total_size_; ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc]; diff --git a/ace/Hash_Map_Manager.h b/ace/Hash_Map_Manager.h index 3800b241b0f..d8c70e9b669 100644 --- a/ace/Hash_Map_Manager.h +++ b/ace/Hash_Map_Manager.h @@ -153,8 +153,10 @@ public: protected: // = The following methods do the actual work. - // These methods assume that the locks are held by the private - // methods. + size_t hash (const EXT_ID &ext_id); + // Compute the hash value of the <ext_id>. + + // = These methods assume locks are held by private methods. int bind_i (const EXT_ID &ext_id, const INT_ID &int_id); // Performs the binding of <ext_id> to <int_id>. Must be diff --git a/ace/LSOCK.h b/ace/LSOCK.h index 6c7c922a830..283d0c87a23 100644 --- a/ace/LSOCK.h +++ b/ace/LSOCK.h @@ -59,6 +59,12 @@ protected: void set_handle (ACE_HANDLE handle); // Set handle. +#if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG) + static const int msg_control_len_ + = sizeof(struct cmsghdr) + sizeof(ACE_HANDLE) ; + // control message size to pass a file descriptor +#endif // ACE_HAS_4_4BSD_SENDMSG_RECVMSG + private: ACE_HANDLE aux_handle_; // An auxiliary handle used to avoid virtual base classes... diff --git a/ace/Local_Name_Space.h b/ace/Local_Name_Space.h index 4d13b1971a1..cee5042db1c 100644 --- a/ace/Local_Name_Space.h +++ b/ace/Local_Name_Space.h @@ -1,8 +1,6 @@ /* -*- C++ -*- */ // $Id$ -/*-*- C++ -*- */ - // ============================================================================ // // = LIBRARY diff --git a/ace/README b/ace/README index ea044cceb2b..0d41b5842db 100644 --- a/ace/README +++ b/ace/README @@ -128,6 +128,7 @@ ACE_HAS_SYSV_SPRINTF Platform/compiler support the System V sprintf(). ACE_HAS_SYS_ERRLIST Platform/compiler supports _sys_errlist symbol ACE_HAS_SYS_FILIO_H Platform provides <sys/filio.h> header ACE_HAS_SYS_SIGLIST Compiler/platform supports _sys_siglist array +ACE_HAS_TEMPLATE_SPECIALIZATION Compiler implements template specialization ACE_HAS_TEMPLATE_TYPEDEFS Compiler implements templates that support typedefs inside of classes used as formal arguments to a template class. ACE_HAS_TERM_IOCTLS Platform has terminal ioctl flags like TCGETS and TCSETS. ACE_HAS_THREADS Platform supports threads diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp index 2559fde2f42..67d87fd76b9 100644 --- a/ace/Strategies_T.cpp +++ b/ace/Strategies_T.cpp @@ -203,6 +203,75 @@ ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy (void) ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) template <class SVC_HANDLER> void +ACE_Reactive_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_Reactive_Strategy<SVC_HANDLER>::open (ACE_Reactor *reactor, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::open"); + this->reactor_ = reactor; + this->mask_ = mask; + + // Must have a <Reactor> + if (this->reactor_ == 0) + return -1; + else + return 0; +} + +template <class SVC_HANDLER> +ACE_Reactive_Strategy<SVC_HANDLER>::ACE_Reactive_Strategy (ACE_Reactor *reactor, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::ACE_Reactive_Strategy"); + + if (this->open (reactor, mask) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_Reactive_Strategy<SVC_HANDLER>::ACE_Reactive_Strategy")); +} + +template <class SVC_HANDLER> +ACE_Reactive_Strategy<SVC_HANDLER>::ACE_Reactive_Strategy (void) + : reactor_ (0), + mask_ (ACE_Event_Handler::NULL_MASK) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::ACE_Reactive_Strategy"); +} + +template <class SVC_HANDLER> +ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy (void) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler"); + + if (this->reactor_ == 0) + return -1; + else if (this->reactor_->register_handler (svc_handler, this->mask_) == -1) + return -1; + // Call up to our parent to do the SVC_HANDLER initialization. + else if (this->inherited::activate_svc_handler (svc_handler, arg) == -1) + { + // Make sure to remove the <svc_handler> from the <Reactor>. + this->reactor_->remove_handler (svc_handler, this->mask_); + return -1; + } + else + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) + +template <class SVC_HANDLER> void ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const { ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::dump"); @@ -210,8 +279,8 @@ ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const template <class SVC_HANDLER> int ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr, - long thr_flags, - int n_threads) + long thr_flags, + size_t n_threads) { ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::open"); this->thr_mgr_ = thr_mgr; @@ -228,11 +297,14 @@ ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr, template <class SVC_HANDLER> ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy (ACE_Thread_Manager *thr_mgr, - long thr_flags, - int n_threads) + long thr_flags, + size_t n_threads) { ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy"); - this->open (thr_mgr, thr_flags, n_threads); + + if (this->open (thr_mgr, thr_flags, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy")); } template <class SVC_HANDLER> diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h index 66947c5b943..268a3e64a9c 100644 --- a/ace/Strategies_T.h +++ b/ace/Strategies_T.h @@ -59,6 +59,7 @@ public: protected: ACE_Thread_Manager *thr_mgr_; + // Pointer to a thread manager. }; template <class SVC_HANDLER> @@ -182,6 +183,55 @@ public: }; template <class SVC_HANDLER> +class ACE_Reactive_Strategy : public ACE_Concurrency_Strategy <SVC_HANDLER> + // = TITLE + // Defines the interface for specifying a Reactive concurrency + // strategy for a SVC_HANDLER. + // + // = DESCRIPTION + // This class provides a strategy that registers the + // <SVC_HANDLER> with a <Reactor>. +{ +public: + // = Intialization and termination methods. + ACE_Reactive_Strategy (void); + // "Do-nothing constructor" + + ACE_Reactive_Strategy (ACE_Reactor *reactor, + ACE_Reactor_Mask = ACE_Event_Handler::READ_MASK); + // Initialize the strategy. + + virtual int open (ACE_Reactor *reactor, + ACE_Reactor_Mask = ACE_Event_Handler::READ_MASK); + // Initialize the strategy. + + virtual ~ACE_Reactive_Strategy (void); + // Destructor. + + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the <svc_handler> by registering it with the <Reactor> + // and then calling it's <open> hook. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; + + ACE_Reactor *reactor_; + // Pointer to the Reactor we'll use to register the <SVC_HANDLER>. + + ACE_Reactor_Mask mask_; + // The mask that we pass to the <Reactor> when we register the + // <SVC_HANDLER>. +}; + +template <class SVC_HANDLER> class ACE_Thread_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> // = TITLE // Defines the interface for specifying a concurrency strategy @@ -201,12 +251,12 @@ public: ACE_Thread_Strategy (ACE_Thread_Manager *tm, long thr_flags, - int n_threads = 1); + size_t n_threads = 1); // Initialize the strategy. virtual int open (ACE_Thread_Manager *tm, long thr_flags, - int n_threads = 1); + size_t n_threads = 1); // Initialize the strategy. virtual ~ACE_Thread_Strategy (void); @@ -234,7 +284,7 @@ protected: long thr_flags_; // Flags to pass into the SVC_HANDLER::activate() method. - int n_threads_; + size_t n_threads_; // Number of threads to spawn. }; diff --git a/ace/config-sunos5.4-centerline-2.x.h b/ace/config-sunos5.4-centerline-2.x.h index 476ddd27a00..0bf46dc40e0 100644 --- a/ace/config-sunos5.4-centerline-2.x.h +++ b/ace/config-sunos5.4-centerline-2.x.h @@ -7,6 +7,8 @@ #if !defined (ACE_CONFIG_H) #define ACE_CONFIG_H +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // Platform supports pread() and pwrite() #define ACE_HAS_P_READ_WRITE diff --git a/ace/config-sunos5.4-g++.h b/ace/config-sunos5.4-g++.h index 88cddd8883f..959634ad222 100644 --- a/ace/config-sunos5.4-g++.h +++ b/ace/config-sunos5.4-g++.h @@ -11,6 +11,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // Platform supports pread() and pwrite() #define ACE_HAS_P_READ_WRITE diff --git a/ace/config-sunos5.4-sunc++-4.x-orbix.h b/ace/config-sunos5.4-sunc++-4.x-orbix.h index 7440259a167..21f0884629c 100644 --- a/ace/config-sunos5.4-sunc++-4.x-orbix.h +++ b/ace/config-sunos5.4-sunc++-4.x-orbix.h @@ -12,6 +12,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // Platform supports pread() and pwrite() #define ACE_HAS_P_READ_WRITE diff --git a/ace/config-sunos5.4-sunc++-4.x.h b/ace/config-sunos5.4-sunc++-4.x.h index 57e7d71db2b..84ca416abe2 100644 --- a/ace/config-sunos5.4-sunc++-4.x.h +++ b/ace/config-sunos5.4-sunc++-4.x.h @@ -11,6 +11,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // Platform supports pread() and pwrite() #define ACE_HAS_P_READ_WRITE diff --git a/ace/config-sunos5.5-g++.h b/ace/config-sunos5.5-g++.h index 461c33e3551..d8ef2d603f1 100644 --- a/ace/config-sunos5.5-g++.h +++ b/ace/config-sunos5.5-g++.h @@ -11,6 +11,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // ACE_HAS_EXCEPTIONS requires -fhandle-exceptions, but that gives // g++ 2.7.2 fits: it spits out all kinds of warnings that it doesn't // without that option (and that are just wrong), and runs out of diff --git a/ace/config-sunos5.5-sunc++-4.1.h b/ace/config-sunos5.5-sunc++-4.1.h index b089b9141ed..8aaceb190d3 100644 --- a/ace/config-sunos5.5-sunc++-4.1.h +++ b/ace/config-sunos5.5-sunc++-4.1.h @@ -14,6 +14,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // ACE_HAS_EXCEPTIONS precludes -noex, but without -noex causes problems // with Sun C++ 4.1/4.2 on multiprocessor UltraSparcs: threaded // executables core dump when threads exit. This problem does not seem diff --git a/ace/config-sunos5.5-sunc++-4.x-orbix.h b/ace/config-sunos5.5-sunc++-4.x-orbix.h index dbfbd6bce0e..2613ece6d0f 100644 --- a/ace/config-sunos5.5-sunc++-4.x-orbix.h +++ b/ace/config-sunos5.5-sunc++-4.x-orbix.h @@ -13,6 +13,8 @@ #define __ACE_INLINE__ #endif /* ! __ACE_INLINE__ */ +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // until we can trust exception handling with Sun C++, it's not enabled . . . // #define ACE_HAS_EXCEPTIONS diff --git a/ace/config-sunos5.5-sunc++-4.x.h b/ace/config-sunos5.5-sunc++-4.x.h index 066e79a593a..8879ec69669 100644 --- a/ace/config-sunos5.5-sunc++-4.x.h +++ b/ace/config-sunos5.5-sunc++-4.x.h @@ -14,6 +14,8 @@ // until we can trust exception handling with Sun C++, it's not enabled . . . // #define ACE_HAS_EXCEPTIONS +#define ACE_HAS_TEMPLATE_SPECIALIZATION + // Platform supports pread() and pwrite() #define ACE_HAS_P_READ_WRITE diff --git a/tests/Map_Manager_Test.cpp b/tests/Map_Manager_Test.cpp index 317847567a2..fc9a45aa92a 100644 --- a/tests/Map_Manager_Test.cpp +++ b/tests/Map_Manager_Test.cpp @@ -27,6 +27,17 @@ typedef ACE_Null_Mutex MUTEX; typedef size_t VALUE; +#if defined (ACE_HAS_TEMPLATE_SPECIALIZATION) +// We need this template specialization since KEY is defined as a +// size_t, which doesn't have a hash() method defined on it. + +size_t +ACE_Hash_Map_Manager<KEY, VALUE, MUTEX>::hash (const KEY& ext_id) +{ + return ext_id; +} +#endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */ + typedef ACE_Map_Manager <KEY, VALUE, MUTEX> MAP_MANAGER; typedef ACE_Map_Iterator <KEY, VALUE, MUTEX> ITERATOR; typedef ACE_Map_Reverse_Iterator <KEY, VALUE, MUTEX> REVERSE_ITERATOR; diff --git a/tests/Pipe_Test.cpp b/tests/Pipe_Test.cpp index 60f265ace09..0073b5ff7c6 100644 --- a/tests/Pipe_Test.cpp +++ b/tests/Pipe_Test.cpp @@ -77,6 +77,7 @@ int main (int argc, char *argv[]) { parse_args (argc, argv); + if (child_process) { ACE_APPEND_LOG ("Pipe_Test-children"); diff --git a/tests/Process_Strategy_Test.cpp b/tests/Process_Strategy_Test.cpp index b1a91ddf06a..b62ffff0d4e 100644 --- a/tests/Process_Strategy_Test.cpp +++ b/tests/Process_Strategy_Test.cpp @@ -10,10 +10,15 @@ // // = DESCRIPTION // This is a test of the <ACE_Strategy_Acceptor> and -// <ACE_File_Lock> classes. The <ACE_Strategy_Acceptor> uses the -// <ACE_Process_Strategy>, which forks a process-per-connection -// and runs as a concurrent server. This concurrent server -// queries and increments a "counting value" in a file. +// <ACE_File_Lock> classes. The <ACE_Strategy_Acceptor> uses +// either the <ACE_Process_Strategy> (which forks a +// process-per-connection and runs as a concurrent server +// process), the <ACE_Thread_Strategy> (which spawns a +// thread-per-connection and runs as a concurrent server thread), +// or <ACE_Reactive_Strategy> (which register the <Svc_Handler> +// with the <Reactor> and runs in the main thread of control as an +// iterative server). This server queries and increments a +// "counting value" in a file. // // To execute this test program you can simply start the server // process and connect to it via telnet. If you type "inc" and @@ -26,12 +31,54 @@ // ============================================================================ #include "ace/Acceptor.h" +#include "ace/Get_Opt.h" #include "ace/SOCK_Acceptor.h" #include "ace/Strategies_T.h" #include "ace/Service_Config.h" +#include "ace/Singleton.h" #include "test_config.h" -#if !defined (ACE_LACKS_EXEC) +class Options + // = TITLE + // Maintains the options for this program. +{ +public: + Options (void); + // Constructor. + + // = Get/set port. + u_short port (void); + void port (u_short); + + enum Concurrency_Strategy + { + PROCESS, + REACTIVE, + THREAD, + MAX_CONCURRENCY_STRATEGY + }; + + // = Get/set concurrency strategy. + Concurrency_Strategy concurrency_strategy (void); + void concurrency_strategy (Concurrency_Strategy); + +private: + u_short port_; + // Port we're listening on. + + Concurrency_Strategy concurrency_strategy_; + // Concurrency strategy that we're running. + + ACE_File_Lock file_lock_; + // Lock for the counting file. + + ACE_Concurrency_Strategy<Counting_Service> *concurrency_strategy_; + // Activation strategy that either forks a new process or spawns a + // new thread for each client connection. +}; + +// Create an options Singleton. +typedef ACE_Singleton<Options, ACE_Null_Mutex> OPTIONS; typedef ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> SVC_HANDLER; @@ -53,24 +100,38 @@ public: // <ACE_Strategy_Acceptor::handle_input>). protected: + // = Methods invoked via "pointer to method" table entry. + + int process (void); + // Handle the PROCESS case. + + virtual int svc (void); + // Handle the THREAD case. + // = Operations corresponding to requests from the client. - virtual int read (void); + int read (void); // Execute the read operation on the file. - virtual int inc (void); + int inc (void); // Execute the increment operation on the file. // = Hooks called by <Reactor> and <Strategy_Acceptor>. - virtual int handle_input (ACE_HANDLE p); + virtual int handle_input (ACE_HANDLE p = ACE_INVALID_HANDLE); // Hook called by the <Reactor> when data arrives from the client. virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); - // Close down the server and exit the process. + // Close down the child and exit the process. private: ACE_File_Lock *file_lock_; // Lock for the counting file. + + typedef int (Counting_Service::*OPERATION) (void); + + OPERATION dispatch_table_[Options::MAX_CONCURRENCY_STRATEGY]; + // Array of pointers to methods that will perform the various types + // of processing. }; typedef ACE_Strategy_Acceptor <Counting_Service, ACE_SOCK_ACCEPTOR> ACCEPTOR; @@ -101,14 +162,44 @@ public: // Catch the SIGCHLD signal and reap the exiting child processes. private: - ACE_File_Lock file_lock_; - // Lock for the counting file. - - ACE_Process_Strategy<Counting_Service> proc_strategy_; - // Activation strategy that forks a new process for each client - // connection. }; +Options::Options (void) + : port_ (ACE_DEFAULT_SERVER_PORT), +#if !defined (ACE_LACKS_EXEC) + concurrency_strategy_ (PROCESS) +#elif defined (ACE_HAS_THREADS) + concurrency_strategy_ (THREAD) +#else + concurrency_strategy_ (REACTIVE) +#endif /* !ACE_LACKS_EXEC */ +{ +} + +u_short +Options::port (void) +{ + return this->port_; +} + +void +Options::port (u_short port) +{ + this->port_ = port; +} + +Options::Concurrency_Strategy +Options::concurrency_strategy (void) +{ + return this->concurrency_strategy_; +} + +void +Options::concurrency_strategy (Options::Concurrency_Strategy cs) +{ + this->concurrency_strategy_ = cs; +} + // Factory Method that creates a new <Counting_Service>. int @@ -124,11 +215,20 @@ int Counting_Acceptor::handle_signal (int signum, siginfo_t *, ucontext_t *) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) signal %S\n", signum)); - - pid_t pid; - while ((pid = ACE_OS::waitpid (-1, 0, WNOHANG)) > 0) - ACE_DEBUG ((LM_DEBUG, "(%P|%t) reaping child %d\n", pid)); + switch (signum) + { + case SIGCHLD: + pid_t pid; + + while ((pid = ACE_OS::waitpid (-1, 0, WNOHANG)) > 0) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) reaping child %d\n", pid)); + break; + + case SIGINT: + ACE_Service_Config::end_reactor_event_loop (); + break; + } return 0; } @@ -158,20 +258,51 @@ Counting_Acceptor::open (const ACE_INET_Addr &addr, ACE_Reactor *reactor) { // Initialize the Concurrency strategy. - if (this->proc_strategy_.open (1, this, reactor) == -1) - return -1; + switch (OPTIONS::instance ()->concurrency_strategy ()) + { + case Options::PROCESS: +#if !defined (ACE_LACKS_EXEC) + ACE_NEW_RETURN (this->concurrency_strategy_, + ACE_Process_Strategy<Counting_Service> (1, this, reactor), + -1); + break; +#else + ACE_ASSERT (!"PROCESS invalid on this platform"); +#endif /* !defined (ACE_LACKS_EXEC) */ + case Options::THREAD: +#if defined (ACE_HAS_THREADS) + ACE_NEW_RETURN (this->concurrency_strategy_, + ACE_Thread_Strategy<Counting_Service> (ACE_Service_Config::thr_mgr (), + THR_NEW_LWP, + 1), + -1); + break; +#else + ACE_ASSERT (!"THREAD invalid on this platform"); +#endif /* !ACE_HAS_THREADS */ + case Options::REACTIVE: + // Settle for the purely Reactive strategy. + ACE_NEW_RETURN (this->concurrency_strategy_, + ACE_Reactive_Strategy<Counting_Service> (ACE_Service_Config::reactor ()), + -1); + break; + } // Open the <Strategy_Acceptor>. - else if (ACCEPTOR::open (addr, + if (ACCEPTOR::open (addr, reactor, 0, 0, - &this->proc_strategy_) == -1) + this->concurrency_strategy_) == -1) return -1; +#if !defined (ACE_WIN32) || !defined (VXWORKS) // Register to handle <SIGCHLD> when a child exits. else if (reactor->register_handler (SIGCHLD, this) == -1) return -1; +#endif /* !defined (ACE_WIN32) || !defined (VXWORKS) */ + else if (reactor->register_handler (SIGINT, this) == -1) + return -1; else { ACE_INET_Addr my_addr; @@ -192,6 +323,9 @@ Counting_Service::Counting_Service (ACE_Thread_Manager *, : file_lock_ (file_lock) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) creating the Counting_Service\n")); + this->dispatch_table_[0] = &Counting_Service::process; + this->dispatch_table_[1] = 0; // Reactive handled via a different approach. + this->dispatch_table_[2] = 0; // Threads are handled via the <svc> hook. } // Read the current value from the shared file and return it to the @@ -291,76 +425,163 @@ Counting_Service::handle_input (ACE_HANDLE) } } -int -Counting_Service::open (void *) +int +Counting_Service::process (void) { - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) opening service\n")); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling process\n")); - // Register the new handle with the reactor and look for new input - // in the handle_input routine. + // Register the new handle with the reactor and look for new + // input in the handle_input routine. if (ACE_Service_Config::reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "(%P|%t) register_handler"), -1); + else + { + // We need to rerun the event loop here since we ended up here + // due to being fork'd and we can't just return to our context + // since it's in the wrong location in the process. + ACE_Service_Config::run_reactor_event_loop (); + return 0; + } +} - // We need to rerun the event loop here since we ended up here due - // to being fork'd and we can't just return to our context since - // it's in the wrong location in the process. - ACE_Service_Config::run_reactor_event_loop (); +int +Counting_Service::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling thread\n")); + + while (this->handle_input () >= 0) + continue; - /* NOTREACHED */ return 0; } +// This method is called back by the <Acceptor> once the client has +// connected and the process is forked or spawned. + +int +Counting_Service::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) opening service\n")); + + Options::Concurrency_Strategy cs = + OPTIONS::instance ()->concurrency_strategy (); + + // Invoke the appropriate pointer to method call. + if (cs < Options::REACTIVE) + return (this->*this->dispatch_table_[cs]) (); + else + return 0; +} + // Hook called when the child is going to exit. int Counting_Service::handle_close (ACE_HANDLE, ACE_Reactor_Mask) { - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) About to exit from the child\n")); + // Initialize the Concurrency strategy. + switch (OPTIONS::instance ()->concurrency_strategy ()) + { + case Options::PROCESS: +#if !defined (ACE_LACKS_EXEC) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) About to exit from the child\n")); - // Exit the child. - ACE_OS::exit (0); + // Exit the child. + ACE_OS::exit (0); + break; +#else + ACE_ASSERT (!"PROCESS invalid on this platform"); +#endif /* !defined (ACE_LACKS_EXEC) */ + case Options::THREAD: +#if defined (ACE_HAS_THREADS) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) exiting thread\n")); + // Call up to complete the close. + SVC_HANDLER::handle_close (); + break; +#else + ACE_ASSERT (!"THREAD invalid on this platform"); +#endif /* !ACE_HAS_THREADS */ + case Options::REACTIVE: + ACE_DEBUG ((LM_DEBUG, "(%P|%t) removing from Reactor\n")); + // Call up to complete the close. + SVC_HANDLER::handle_close (); + break; + } return 0; } + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + "usage: %n [-p (port)] [-c (concurrency strategy)] \n")); + ACE_OS::exit (1); +} + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "p:c:"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'p': + OPTIONS::instance ()->port (ACE_OS::atoi (get_opt.optarg)); + break; + case 'c': + if (ACE_OS::strcmp (get_opt.optarg, "REACTIVE") == 0) + OPTIONS::instance ()->concurrency_strategy (Options::REACTIVE); +#if !defined (ACE_LACKS_EXEC) + else if (ACE_OS::strcmp (get_opt.optarg, "PROCESS") == 0) + OPTIONS::instance ()->concurrency_strategy (Options::PROCESS); #endif /* !ACE_LACKS_EXEC */ +#if defined (ACE_HAS_THREADS) + else if (ACE_OS::strcmp (get_opt.optarg, "THREAD") == 0) + OPTIONS::instance ()->concurrency_strategy (Options::THREAD); +#endif /* ACE_HAS_THREADS */ + break; + default: + print_usage_and_die (); + break; + } +} int main (int argc, char *argv[]) { - ACE_START_TEST ("Process_Stratey_Test"); + // ACE_START_TEST ("Process_Stratey_Test"); -#if !defined (ACE_LACKS_EXEC) ACE_Service_Config svc_conf; // Initialize the counting file. - Counting_Acceptor counting_acceptor (__TEXT ("counting_file")); - - u_short port = ACE_DEFAULT_SERVER_PORT; + Counting_Acceptor counting_acceptor (ACE_TEMP_FILE_NAME); - if (argc > 1) - port = ACE_OS::atoi (argv[1]); - - ACE_INET_Addr addr (port); + parse_args (argc, argv); + + ACE_INET_Addr addr (OPTIONS::instance ()->port ()); - // Open the Acceptor. + // Open the Acceptor and listen at <addr>. if (counting_acceptor.open (addr) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); - // Run the event loop. + // Run the main event loop. ACE_Service_Config::run_reactor_event_loop (); -#else - ACE_ERROR ((LM_ERROR, "fork() not supported on this platform\n")); -#endif /* !ACE_LACKS_EXEC */ - ACE_END_TEST; + // Remove the filename. + ACE_OS::unlink (ACE_TEMP_FILE_NAME); + + // ACE_END_TEST; return 0; } - #if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) template class ACE_Accept_Strategy<Counting_Service, ACE_SOCK_ACCEPTOR>; template class ACE_Acceptor<Counting_Service, ACE_SOCK_ACCEPTOR>; @@ -370,6 +591,8 @@ template class ACE_Guard<ACE_File_Lock>; template class ACE_Message_Queue<ACE_NULL_SYNCH>; template class ACE_Module<ACE_NULL_SYNCH>; template class ACE_Process_Strategy<Counting_Service>; +template class ACE_Thread_Strategy<Counting_Service>; +template class ACE_Reactive_Strategy<Counting_Service>; template class ACE_Read_Guard<ACE_File_Lock>; template class ACE_Scheduling_Strategy<Counting_Service>; template class ACE_Strategy_Acceptor<Counting_Service, ACE_SOCK_ACCEPTOR>; diff --git a/tests/test_config.h b/tests/test_config.h index 23f3c9a9349..0608be4ca34 100644 --- a/tests/test_config.h +++ b/tests/test_config.h @@ -17,6 +17,7 @@ #include <iostream.h> #include <fstream.h> +#if !defined (ACE_HAS_TEMPLATE_SPECIALIZATION) class KEY // ============================================================================ // = TITLE @@ -38,6 +39,9 @@ public: private: size_t value_; }; +#else +typedef size_t KEY; +#endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */ #if defined (ACE_WIN32) |