summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1997-04-23 04:26:25 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1997-04-23 04:26:25 +0000
commit35d953eb3aef94113f388d8079688e96a4a327aa (patch)
tree18c6cc58e4961fdf9908868a8dd4647126a88d02
parent296af34a9b459fa56355903b15216f09e6f4897b (diff)
downloadATCD-35d953eb3aef94113f388d8079688e96a4a327aa.tar.gz
*** empty log message ***
-rw-r--r--ChangeLog-97a84
-rw-r--r--ace/Hash_Map_Manager.cpp14
-rw-r--r--ace/Hash_Map_Manager.h6
-rw-r--r--ace/LSOCK.h6
-rw-r--r--ace/Local_Name_Space.h2
-rw-r--r--ace/README1
-rw-r--r--ace/Strategies_T.cpp82
-rw-r--r--ace/Strategies_T.h56
-rw-r--r--ace/config-sunos5.4-centerline-2.x.h2
-rw-r--r--ace/config-sunos5.4-g++.h2
-rw-r--r--ace/config-sunos5.4-sunc++-4.x-orbix.h2
-rw-r--r--ace/config-sunos5.4-sunc++-4.x.h2
-rw-r--r--ace/config-sunos5.5-g++.h2
-rw-r--r--ace/config-sunos5.5-sunc++-4.1.h2
-rw-r--r--ace/config-sunos5.5-sunc++-4.x-orbix.h2
-rw-r--r--ace/config-sunos5.5-sunc++-4.x.h2
-rw-r--r--tests/Map_Manager_Test.cpp11
-rw-r--r--tests/Pipe_Test.cpp1
-rw-r--r--tests/Process_Strategy_Test.cpp331
-rw-r--r--tests/test_config.h4
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)