diff options
Diffstat (limited to 'ACE/examples/APG')
241 files changed, 17841 insertions, 0 deletions
diff --git a/ACE/examples/APG/Active_Objects/.cvsignore b/ACE/examples/APG/Active_Objects/.cvsignore new file mode 100644 index 00000000000..2af94b7dd8c --- /dev/null +++ b/ACE/examples/APG/Active_Objects/.cvsignore @@ -0,0 +1,4 @@ +AO +AO +AO2 +AO2 diff --git a/ACE/examples/APG/Active_Objects/AO.cpp b/ACE/examples/APG/Active_Objects/AO.cpp new file mode 100644 index 00000000000..b84a017d590 --- /dev/null +++ b/ACE/examples/APG/Active_Objects/AO.cpp @@ -0,0 +1,186 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_unistd.h" +#include "ace/Activation_Queue.h" +#include "ace/Method_Request.h" +#include "ace/Task.h" +#include "ace/Future.h" +#include "ace/Auto_Ptr.h" +// Listing 1 code/ch15 +class HA_ControllerAgent +{ + // Proxy to the HA_Controller that is on the network. +public: + HA_ControllerAgent () + { + ACE_TRACE + (ACE_TEXT ("HA_ControllerAgent::HA_ControllerAgent")); + status_result_ = 1; + } + + int status_update (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgent::status_update")); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Obtaining a status_update in %t ") + ACE_TEXT ("thread of control\n"))); + // Simulate time to send message and get status. + ACE_OS::sleep (2); + return next_result_id (); + } + +private: + int next_result_id (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgent::next_cmd_id")); + return status_result_++; + } + + int status_result_; +}; +// Listing 1 +// Listing 2 code/ch15 +class StatusUpdate : public ACE_Method_Request +{ +public: + StatusUpdate (HA_ControllerAgent& controller, + ACE_Future<int>& returnVal) + : controller_(controller), returnVal_(returnVal) + { + ACE_TRACE (ACE_TEXT ("StatusUpdate::StatusUpdate")); + } + + virtual int call (void) + { + ACE_TRACE (ACE_TEXT ("StatusUpdate::call")); + + // status_update with the controller. + this->returnVal_.set (this->controller_.status_update ()); + return 0; + } + +private: + HA_ControllerAgent& controller_; + ACE_Future<int> returnVal_; +}; +// Listing 2 +// Listing 3 code/ch15 +class ExitMethod : public ACE_Method_Request +{ +public: + virtual int call (void) + { + // Cause exit. + return -1; + } +}; +// Listing 3 +// Listing 4 code/ch15 +class Scheduler : public ACE_Task_Base +{ +public: + Scheduler () + { + ACE_TRACE (ACE_TEXT ("Scheduler::Scheduler")); + this->activate (); + } + + virtual int svc (void) + { + ACE_TRACE (ACE_TEXT ("Scheduler::svc")); + + while (1) + { + // Dequeue the next method object + auto_ptr<ACE_Method_Request> + request (this->activation_queue_.dequeue ()); + + // Invoke the method request. + if (request->call () == -1) + break; + } + + return 0; + } + + int enqueue (ACE_Method_Request *request) + { + ACE_TRACE (ACE_TEXT ("Scheduler::enqueue")); + return this->activation_queue_.enqueue (request); + } + +private: + ACE_Activation_Queue activation_queue_; +}; +// Listing 4 +// Listing 5 code/ch15 +class HA_ControllerAgentProxy +{ + // This acts as a Proxy to the controller impl object. +public: + ACE_Future<int> status_update (void) + { + ACE_TRACE + (ACE_TEXT ("HA_ControllerAgentProxy::status_update")); + ACE_Future<int> result; + + // Create and enqueue a method request on the scheduler. + this->scheduler_.enqueue + (new StatusUpdate (this->controller_, result)); + + // Return Future to the client. + return result; + } + + void exit (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgentProxy::exit")); + this->scheduler_.enqueue (new ExitMethod); + } + +private: + Scheduler scheduler_; + HA_ControllerAgent controller_; +}; +// Listing 5 +// Listing 6 code/ch15 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_ControllerAgentProxy controller; + ACE_Future<int> results[10]; + + for (int i = 0 ; i < 10; i++) + results[i] = controller.status_update (); + + ACE_OS::sleep (5); // Do other work. + + // Get results... + for (int j = 0; j < 10; j++) + { + int result = 0; + results[j].get (result); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("New status_update %d\n"), result)); + } + + // Cause the status_updater threads to exit. + controller.exit (); + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +// Listing 6 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Active_Objects/AO2.cpp b/ACE/examples/APG/Active_Objects/AO2.cpp new file mode 100644 index 00000000000..04553c8e1b8 --- /dev/null +++ b/ACE/examples/APG/Active_Objects/AO2.cpp @@ -0,0 +1,196 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_unistd.h" +#include "ace/Activation_Queue.h" +#include "ace/Method_Request.h" +#include "ace/Task.h" +#include "ace/Future.h" +#include "ace/Auto_Ptr.h" + +class HA_ControllerAgent +{ + // Proxy to the HA_Controller that is on the network. +public: + HA_ControllerAgent () + { + ACE_TRACE + (ACE_TEXT ("HA_ControllerAgent::HA_ControllerAgent")); + status_result_ = 1; + } + + int status_update (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgent::status_update")); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Obtaining a status_update in %t ") + ACE_TEXT ("thread of control\n"))); + // Simulate sending message to controller + // and getting status. + ACE_OS::sleep (2); + return next_result_id (); + } + +private: + int next_result_id (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgent::next_cmd_id")); + return status_result_++; + } + + int status_result_; +}; + +class StatusUpdate : public ACE_Method_Request +{ +public: + StatusUpdate (HA_ControllerAgent& controller, + ACE_Future<int>& returnVal) + : controller_(controller), returnVal_(returnVal) + { + ACE_TRACE (ACE_TEXT ("StatusUpdate::StatusUpdate")); + } + + virtual int call (void) + { + ACE_TRACE (ACE_TEXT ("StatusUpdate::call")); + + // status_update with the controller. + this->returnVal_.set (this->controller_.status_update ()); + return 0; + } + +private: + HA_ControllerAgent& controller_; + ACE_Future<int> returnVal_; +}; + +class ExitMethod : public ACE_Method_Request +{ +public: + virtual int call (void) + { + // Cause exit. + return -1; + } +}; + +class Scheduler : public ACE_Task_Base +{ +public: + Scheduler () + { + ACE_TRACE (ACE_TEXT ("Scheduler::Scheduler")); + this->activate (); + } + + virtual int svc (void) + { + ACE_TRACE (ACE_TEXT ("Scheduler::svc")); + + while (1) + { + // Dequeue the next method object + auto_ptr<ACE_Method_Request> + request (this->activation_queue_.dequeue ()); + + // Invoke the method request. + if (request->call () == -1) + break; + } + + return 0; + } + + int enqueue (ACE_Method_Request *request) + { + ACE_TRACE (ACE_TEXT ("Scheduler::enqueue")); + return this->activation_queue_.enqueue (request); + } + +private: + ACE_Activation_Queue activation_queue_; +}; + +class HA_ControllerAgentProxy +{ + // This acts as a Proxy to the controller impl object. +public: + ACE_Future<int> status_update (void) + { + ACE_TRACE + (ACE_TEXT ("HA_ControllerAgentProxy::status_update")); + ACE_Future<int> result; + + // Create and enqueue a method request on the scheduler. + this->scheduler_.enqueue + (new StatusUpdate (this->controller_, result)); + + // Return Future to the client. + return result; + } + + void exit (void) + { + ACE_TRACE (ACE_TEXT ("HA_ControllerAgentProxy::exit")); + this->scheduler_.enqueue (new ExitMethod); + } + +private: + Scheduler scheduler_; + HA_ControllerAgent controller_; +}; + +// Listing 1 code/ch15 +class CompletionCallBack : public ACE_Future_Observer<int> +{ +public: + CompletionCallBack (HA_ControllerAgentProxy& proxy) + : proxy_(proxy) + { } + + virtual void update (const ACE_Future<int>& future) + { + int result = 0; + ((ACE_Future<int>)future).get (result); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%t) New Status %d\n"), result)); + if (result == 10) + this->proxy_.exit (); + } + +private: + HA_ControllerAgentProxy& proxy_; +}; +// Listing 1 +// Listing 2 code/ch15 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_ControllerAgentProxy controller; + ACE_Future<int> results[10]; + CompletionCallBack cb (controller); + + for (int i = 0 ; i < 10; i++) + { + results[i] = controller.status_update (); + results[i].attach (&cb); + } + + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +// Listing 2 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Active_Objects/Makefile.am b/ACE/examples/APG/Active_Objects/Makefile.am new file mode 100644 index 00000000000..4562743bc87 --- /dev/null +++ b/ACE/examples/APG/Active_Objects/Makefile.am @@ -0,0 +1,56 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.AO.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += AO + +AO_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +AO_SOURCES = \ + AO.cpp + +AO_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.AO2.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += AO2 + +AO2_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +AO2_SOURCES = \ + AO2.cpp + +AO2_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Active_Objects/active_objects.mpc b/ACE/examples/APG/Active_Objects/active_objects.mpc new file mode 100644 index 00000000000..44fe88bfd30 --- /dev/null +++ b/ACE/examples/APG/Active_Objects/active_objects.mpc @@ -0,0 +1,18 @@ +// -*- MPC -*- +// $Id$ + +project(AO) : aceexe { + avoids += ace_for_tao + exename = AO + Source_Files { + AO.cpp + } +} + +project(AO2) : aceexe { + avoids += ace_for_tao + exename = AO2 + Source_Files { + AO2.cpp + } +} diff --git a/ACE/examples/APG/Config/.cvsignore b/ACE/examples/APG/Config/.cvsignore new file mode 100644 index 00000000000..b9f807ab7a6 --- /dev/null +++ b/ACE/examples/APG/Config/.cvsignore @@ -0,0 +1,6 @@ +ARGV_Example +ARGV_Example +Get_Opt +Get_Opt +Get_Opt_Long +Get_Opt_Long diff --git a/ACE/examples/APG/Config/ARGV_Example.cpp b/ACE/examples/APG/Config/ARGV_Example.cpp new file mode 100644 index 00000000000..92fb25cd30d --- /dev/null +++ b/ACE/examples/APG/Config/ARGV_Example.cpp @@ -0,0 +1,62 @@ +/** + * $Id$ + * + * ACE_ARGV examples not in a larger program. Sample code from The ACE + * Programmer's Guide, Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/os_include/os_netdb.h" +#include "ace/OS_NS_string.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch04 +#include "ace/ARGV.h" +#include "ace/Get_Opt.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + static const ACE_TCHAR options[] = ACE_TEXT (":f:h:"); + static const ACE_TCHAR cmdline[] = + ACE_TEXT ("-f /home/managed.cfg -h $HOSTNAME"); + ACE_ARGV cmdline_args (cmdline); + ACE_Get_Opt cmd_opts (cmdline_args.argc (), + cmdline_args.argv (), + options, + 0); // Don't skip any args + +// Listing 1 + + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_TCHAR hostname[MAXHOSTNAMELEN]; + ACE_OS_String::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + ACE_OS_String::strcpy (hostname, ACE_TEXT ("not set")); + while ((option = cmd_opts ()) != EOF) + switch (option) { + case 'f': + ACE_OS_String::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + + case 'h': + ACE_OS_String::strncpy (hostname, + cmd_opts.opt_arg (), + MAXHOSTNAMELEN); + break; + + case ':': + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), -1); + + + default: + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Parse error.\n")), -1); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Config file: %s\n"), config_file)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Hostname: %s\n"), hostname)); + return 0; +} diff --git a/ACE/examples/APG/Config/Get_Opt.cpp b/ACE/examples/APG/Config/Get_Opt.cpp new file mode 100644 index 00000000000..604dc38326e --- /dev/null +++ b/ACE/examples/APG/Config/Get_Opt.cpp @@ -0,0 +1,59 @@ +/** + * $Id$ + * + * ACE_Get_Opt examples not in a larger program. Sample code from The ACE + * Programmer's Guide, Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/OS_NS_string.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + + // Example for a long option without a corresponding short option. + // Just put some context here so the following compiles and runs. + static const ACE_TCHAR options[] = ACE_TEXT (":f:"); + ACE_Get_Opt cmd_opts (argc, argv, options); + + // Listing 1 code/ch04 + cmd_opts.long_option (ACE_TEXT ("cool_option")); + cmd_opts.long_option (ACE_TEXT ("the_answer"), 42); + // Listing 1 + + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_OS_String::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + while ((option = cmd_opts ()) != EOF) + switch (option) { + case 'f': + ACE_OS_String::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + + // Listing 2 code/ch04 + case 0: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Yes, very cool.\n"))); + break; + + case 42: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("the_answer is 42\n"))); + break; + // Listing 2 + + case ':': + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), -1); + + + default: + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Parse error.\n")), -1); + } + + return 0; +} diff --git a/ACE/examples/APG/Config/Get_Opt_Long.cpp b/ACE/examples/APG/Config/Get_Opt_Long.cpp new file mode 100644 index 00000000000..66baed05cdb --- /dev/null +++ b/ACE/examples/APG/Config/Get_Opt_Long.cpp @@ -0,0 +1,48 @@ +/** + * $Id$ + * + * ACE_Get_Opt long_only examples. Sample code from The ACE + * Programmer's Guide, Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/OS_NS_string.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + + static const ACE_TCHAR options[] = ACE_TEXT (":f:"); + ACE_Get_Opt cmd_opts + (argc, argv, options, 1, 0, ACE_Get_Opt::PERMUTE_ARGS, 1); + if (cmd_opts.long_option + (ACE_TEXT ("config"), 'f', ACE_Get_Opt::ARG_REQUIRED) == -1) + return -1; + + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_OS_String::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + while ((option = cmd_opts ()) != EOF) + switch (option) { + case 'f': + ACE_OS_String::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + + case ':': + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), -1); + + + default: + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Parse error.\n")), -1); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Config file is %s\n"), config_file)); + + return 0; +} diff --git a/ACE/examples/APG/Config/HASTATUS_export.h b/ACE/examples/APG/Config/HASTATUS_export.h new file mode 100644 index 00000000000..09fe1797f80 --- /dev/null +++ b/ACE/examples/APG/Config/HASTATUS_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl HASTATUS +// ------------------------------ +#ifndef HASTATUS_EXPORT_H +#define HASTATUS_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (HASTATUS_HAS_DLL) +# define HASTATUS_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ! HASTATUS_HAS_DLL */ + +#if !defined (HASTATUS_HAS_DLL) +# define HASTATUS_HAS_DLL 1 +#endif /* ! HASTATUS_HAS_DLL */ + +#if defined (HASTATUS_HAS_DLL) && (HASTATUS_HAS_DLL == 1) +# if defined (HASTATUS_BUILD_DLL) +# define HASTATUS_Export ACE_Proper_Export_Flag +# define HASTATUS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* HASTATUS_BUILD_DLL */ +# define HASTATUS_Export ACE_Proper_Import_Flag +# define HASTATUS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* HASTATUS_BUILD_DLL */ +#else /* HASTATUS_HAS_DLL == 1 */ +# define HASTATUS_Export +# define HASTATUS_SINGLETON_DECLARATION(T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* HASTATUS_HAS_DLL == 1 */ + +// Set HASTATUS_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (HASTATUS_NTRACE) +# if (ACE_NTRACE == 1) +# define HASTATUS_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define HASTATUS_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !HASTATUS_NTRACE */ + +#if (HASTATUS_NTRACE == 1) +# define HASTATUS_TRACE(X) +#else /* (HASTATUS_NTRACE == 1) */ +# define HASTATUS_TRACE(X) ACE_TRACE_IMPL(X) +#endif /* (HASTATUS_NTRACE == 1) */ + +#endif /* HASTATUS_EXPORT_H */ + +// End of auto generated file. diff --git a/ACE/examples/APG/Config/HA_Status.cpp b/ACE/examples/APG/Config/HA_Status.cpp new file mode 100644 index 00000000000..1bad687be80 --- /dev/null +++ b/ACE/examples/APG/Config/HA_Status.cpp @@ -0,0 +1,98 @@ +/** + * $Id$ + * + * Home Automation Status server. Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/OS_NS_string.h" +#include "ace/Configuration.h" +#include "ace/Configuration_Import_Export.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/Service_Object.h" + +class HA_Status : public ACE_Service_Object +{ +public: + virtual int init (int argc, ACE_TCHAR *argv[]); + +private: + ACE_INET_Addr listen_addr_; +}; + + +int +HA_Status::init (int argc, ACE_TCHAR *argv[]) +{ + + // Do ACE_Get_Opt and get conf file name, read out the sections + // and print the names. + + // Listing 1 code/ch04 + static const ACE_TCHAR options[] = ACE_TEXT (":f:"); + ACE_Get_Opt cmd_opts (argc, argv, options); + if (cmd_opts.long_option + (ACE_TEXT ("config"), 'f', ACE_Get_Opt::ARG_REQUIRED) == -1) + return -1; + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_OS::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + while ((option = cmd_opts ()) != EOF) + switch (option) { + case 'f': + ACE_OS::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + case ':': + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), -1); + default: + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Parse error.\n")), -1); + } + // Listing 1 + + // Listing 2 code/ch04 + ACE_Configuration_Heap config; + if (config.open () == -1) + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("config")), -1); + ACE_Registry_ImpExp config_importer (config); + if (config_importer.import_config (config_file) == -1) + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("%p\n"), config_file), -1); + + ACE_Configuration_Section_Key status_section; + if (config.open_section (config.root_section (), + ACE_TEXT ("HAStatus"), + 0, + status_section) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Can't open HAStatus section")), + -1); + + u_int status_port; + if (config.get_integer_value (status_section, + ACE_TEXT ("ListenPort"), + status_port) == -1) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("HAStatus ListenPort does not exist\n")), + -1); + this->listen_addr_.set (static_cast<u_short> (status_port)); + // Listing 2 + + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + HA_Status status; + status.init (argc, argv); + return 0; +} diff --git a/ACE/examples/APG/Config/Makefile.am b/ACE/examples/APG/Config/Makefile.am new file mode 100644 index 00000000000..5320bfdf85c --- /dev/null +++ b/ACE/examples/APG/Config/Makefile.am @@ -0,0 +1,81 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.ARGV_Example.am +noinst_PROGRAMS = ARGV_Example + +ARGV_Example_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ARGV_Example_SOURCES = \ + ARGV_Example.cpp \ + HASTATUS_export.h + +ARGV_Example_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Config_HA_Status.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += HA_Status + +HA_Status_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HA_Status_SOURCES = \ + HA_Status.cpp \ + HASTATUS_export.h + +HA_Status_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Get_Opt.am +noinst_PROGRAMS += Get_Opt + +Get_Opt_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Get_Opt_SOURCES = \ + Get_Opt.cpp \ + HASTATUS_export.h + +Get_Opt_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Get_Opt_Long.am +noinst_PROGRAMS += Get_Opt_Long + +Get_Opt_Long_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Get_Opt_Long_SOURCES = \ + Get_Opt_Long.cpp \ + HASTATUS_export.h + +Get_Opt_Long_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Config/config.mpc b/ACE/examples/APG/Config/config.mpc new file mode 100644 index 00000000000..5b705d144bc --- /dev/null +++ b/ACE/examples/APG/Config/config.mpc @@ -0,0 +1,31 @@ +// -*- MPC -*- +// $Id$ + +project(*HA Status) : aceexe { + avoids += ace_for_tao + exename = HA_Status + Source_Files { + HA_Status.cpp + } +} + +project(Get Opt) : aceexe { + exename = Get_Opt + Source_Files { + Get_Opt.cpp + } +} + +project(Get Opt Long) : aceexe { + exename = Get_Opt_Long + Source_Files { + Get_Opt_Long.cpp + } +} + +project(ARGV Example) : aceexe { + exename = ARGV_Example + Source_Files { + ARGV_Example.cpp + } +} diff --git a/ACE/examples/APG/Containers/.cvsignore b/ACE/examples/APG/Containers/.cvsignore new file mode 100644 index 00000000000..20d09b55a72 --- /dev/null +++ b/ACE/examples/APG/Containers/.cvsignore @@ -0,0 +1,24 @@ +Allocator +Allocator +Array +Array +DLList +DLList +Hash_Map +Hash_Map +Hash_Map_Hash +Hash_Map_Hash +Map_Manager +Map_Manager +Map_Manager_Specialization +Map_Manager_Specialization +Queues +Queues +RB_Tree +RB_Tree +RB_Tree_Functors +RB_Tree_Functors +Sets +Sets +Stacks +Stacks diff --git a/ACE/examples/APG/Containers/Allocator.cpp b/ACE/examples/APG/Containers/Allocator.cpp new file mode 100644 index 00000000000..847235a3061 --- /dev/null +++ b/ACE/examples/APG/Containers/Allocator.cpp @@ -0,0 +1,93 @@ +// $Id$ + +#include "ace/Containers.h" +#include "ace/Malloc_T.h" +#include "ace/Synch.h" // Needed for the lock. +#include "DataElement.h" + +class StackExample +{ +public: + // Illustrate all the differnet + // types of stacks provided by ACE. + int run (void); + +private: + // Illustrate the use of an unbounded stack. + int runUnboundedStack (ACE_Allocator* allocator); +}; + +// Listing 1 code/ch05 +int StackExample::run (void) +{ + ACE_TRACE (ACE_TEXT ("StackUser::run")); + + ACE_Allocator *allocator = 0; + size_t block_size = sizeof(ACE_Node<DataElement>); + ACE_NEW_RETURN + (allocator, + ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> + (100 + 1, block_size), + -1); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + ACE_ASSERT (this->runUnboundedStack (allocator) != -1); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + delete allocator; + return 0; +} +// Listing 1 +// Listing 2 code/ch05 +int StackExample::runUnboundedStack (ACE_Allocator* allocator) +{ + ACE_TRACE (ACE_TEXT ("StackExample::runUnboundedStack")); + + // Pass in an allocator during construction. + ACE_Unbounded_Stack<DataElement> ustack (allocator); + + for (int m = 0; m < 100; m++) + { + DataElement elem (m); + int result = ustack.push (elem); + if (result == -1) + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Push Next Element")), + -1); + } + + void* furtherMemory = 0; + furtherMemory = allocator->malloc + (sizeof(ACE_Node<DataElement>)); + ACE_ASSERT (furtherMemory == 0); + + // No memory left.. + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%p\n"), + ACE_TEXT ("No memory.."))); + + // Free up some memory in the allocator. + DataElement e; + for (int n = 0; n < 10; n++) + { + ustack.pop (e); + } + + furtherMemory = + allocator->malloc (sizeof (ACE_Node<DataElement>)); + ACE_ASSERT (furtherMemory != 0); + + return 0; +} +// Listing 2 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + StackExample se; + return se.run (); +} + diff --git a/ACE/examples/APG/Containers/Array.cpp b/ACE/examples/APG/Containers/Array.cpp new file mode 100644 index 00000000000..1ffb19f22e9 --- /dev/null +++ b/ACE/examples/APG/Containers/Array.cpp @@ -0,0 +1,41 @@ +// $Id$ + +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" +// Listing 1 code/ch05 +#include "ace/Containers.h" +#include "DataElement.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Array<DataElement*> arr (10); + DataElement *elem = 0; + // Allocate and insert elements. + for (int i = 0; i < 10; i++) + { + ACE_NEW_RETURN (elem, DataElement (i), -1); + arr[i] = elem; + } + + // Checked access. + ACE_ASSERT (arr.set (elem, 11) == -1); + ACE_ASSERT (arr.get (elem, 11) == -1); + + // Make a copy and compare to the original. + ACE_Array<DataElement*> copy = arr; + ACE_ASSERT (copy == arr); + + ACE_Array<DataElement*>::ITERATOR iter (arr); + while (!iter.done ()) + { + DataElement** data; + iter.next (data); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%d\n"), (*data)->getData ())); + delete (*data); + iter.advance (); + } + return 0; +} +// Listing 1 + diff --git a/ACE/examples/APG/Containers/DLList.cpp b/ACE/examples/APG/Containers/DLList.cpp new file mode 100644 index 00000000000..8c93e5b4039 --- /dev/null +++ b/ACE/examples/APG/Containers/DLList.cpp @@ -0,0 +1,116 @@ +// $Id$ + +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch05 +#include "ace/Containers.h" +#include "DataElement.h" + +// Create a new type of list that can store only DataElements. +typedef ACE_DLList<DataElement> MyList; +// Listing 1 + +// Listing 2 code/ch05 +class ListTest +{ +public: + int run (void); + void displayList (MyList & list); // Display all elements. + void destroyList (MyList& list); // Destroy all elements. +}; +// Listing 2 +// Listing 3 code/ch05 +int +ListTest::run (void) +{ + ACE_TRACE (ACE_TEXT ("ListTest::run")); + + // Create a list and insert 100 elements. + MyList list1; + + for (int i = 0; i < 100; i++) + { + DataElement *element; + ACE_NEW_RETURN (element, DataElement (i), -1); + list1.insert_tail (element); + } + + // Iterate through and display to output. + this->displayList (list1); + + // Create a copy of list1. + MyList list2; + list2 = list1; + + // Iterate over the copy and display it to output. + this->displayList(list2); + + // Get rid of the copy list and all its elements. + // Since both lists had the *same* elements + // this will cause list1 to contain pointers that + // point to data elements that have already been destroyed! + this->destroyList (list2); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("# of live objects: %d\n"), + DataElement::numOfActiveObjects())); + + // The lists themselves are destroyed here. Note that the + // list destructor will destroy copies of whatever data the + // list contained. Since in this case the list contained + // copies of pointers to the data elements these are the + // only thing that gets destroyed here. + return 0; +} +// Listing 3 +// Listing 4 code/ch05 +void +ListTest::destroyList (MyList& list) +{ + ACE_TRACE (ACE_TEXT ("ListTest::destroyList")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Destroying data elements\n"))); + + // Iterate through and delete all the data elements on the list. + for (ACE_DLList_Iterator<DataElement> iter (list); + !iter.done (); + iter++) + { + DataElement *de = iter.next (); + delete de; + } +} +// Listing 4 +// Listing 5 code/ch05 +void +ListTest::displayList (MyList& list) +{ + ACE_TRACE (ACE_TEXT ("ListTest::displayList")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); + ACE_DLList_Iterator<DataElement> iter (list); + while (!iter.done ()) + { + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("%d:"), iter.next()->getData())); + iter++; + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration \n"))); + ACE_DLList_Reverse_Iterator<DataElement> riter (list); + while (!riter.done ()) + { + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("%d:"), riter.next()->getData())); + riter++; + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} +// Listing 5 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ListTest test; + return test.run (); +} + diff --git a/ACE/examples/APG/Containers/DataElement.h b/ACE/examples/APG/Containers/DataElement.h new file mode 100644 index 00000000000..cd09d86fa87 --- /dev/null +++ b/ACE/examples/APG/Containers/DataElement.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(DATAELEMENT_H) +#define DATAELEMENT_H + +class DataElementEx; + +// Listing 1 code/ch05 +// A simple data element class. +class DataElement +{ + friend class DataElementEx; + +public: + DataElement () : data_ (0) { count_++; } + + DataElement (int data) : data_(data) { count_++; } + + DataElement (const DataElement& e) + { + data_ = e.getData (); + count_++; + } + + DataElement & operator= (const DataElement& e) + { + data_ = e.getData (); + return *this; + } + + bool operator== (const DataElement& e) + { return this->data_ == e.data_; } + + ~DataElement () { count_--; } + + int getData (void) const { return data_; } + + void setData (int val) { data_ = val; } + + static int numOfActiveObjects (void) { return count_; } + + private: + int data_; + static int count_; +}; +// Listing 1 + +int DataElement::count_ = 0; + +#endif /*DATAELEMENT_H*/ + diff --git a/ACE/examples/APG/Containers/Hash_Map.cpp b/ACE/examples/APG/Containers/Hash_Map.cpp new file mode 100644 index 00000000000..1b2d4ee4634 --- /dev/null +++ b/ACE/examples/APG/Containers/Hash_Map.cpp @@ -0,0 +1,118 @@ +// $Id$ + +#include "ace/Hash_Map_Manager.h" +#include "ace/Synch.h" // needed for the lock +#include "ace/Functor.h" +#include "DataElement.h" + +// Listing 1 code/ch05 +// Little helper class. +template<class EXT_ID, class INT_ID> +class Hash_Map : + public ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, + ACE_Hash<EXT_ID>, ACE_Equal_To<EXT_ID>, ACE_Null_Mutex> +{}; +// Listing 1 + +class Hash_Map_Example +{ +public: + // Constructor + Hash_Map_Example (); + + // Illustrate the hash map. + int run (void); + + // Use the forward iterator. + void iterate_forward (void); + + // Use the reverse iterator. + void iterate_reverse (void); + + // Remove all the elements from the map. + void remove_all (void); + +private: + Hash_Map<int, DataElement> map_; +}; + +// Listing 2 code/ch05 +Hash_Map_Example::Hash_Map_Example() +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::Hash_Map_Example")); + + map_.open (100); +} +// Listing 2 + +int Hash_Map_Example::run (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::run")); + + for (int i = 0; i < 100; i++) + { + map_.bind (i, DataElement(i)); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has \n"))); + for (int j = 0; j < 100; j++) + { + DataElement d; + map_.find (j,d); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Use the forward iterator. + this->iterate_forward (); + + // Use the reverse iterator. + this->iterate_reverse (); + + // Remove all the elements from the map. + this->remove_all (); + + // Iterate through the map again. + this->iterate_forward (); + + return 0; +} + +void Hash_Map_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration \n"))); + for (Hash_Map<int, DataElement>::iterator iter = map_.begin (); + iter != map_.end (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Hash_Map_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::iterate_reverse")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration \n"))); + for (Hash_Map<int, DataElement>::reverse_iterator iter = map_.rbegin (); + iter != map_.rend (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Hash_Map_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::remove_all")); + map_.unbind_all (); +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Hash_Map_Example me; + return me.run (); +} + diff --git a/ACE/examples/APG/Containers/Hash_Map_Hash.cpp b/ACE/examples/APG/Containers/Hash_Map_Hash.cpp new file mode 100644 index 00000000000..faad3c72585 --- /dev/null +++ b/ACE/examples/APG/Containers/Hash_Map_Hash.cpp @@ -0,0 +1,111 @@ +// $Id$ + +#include "ace/Hash_Map_Manager.h" +#include "ace/Synch.h" // Needed for the lock +#include "ace/Functor.h" +#include "DataElement.h" +#include "Hash_Map_Hash.h" + +// Little helper class +template<class EXT_ID, class INT_ID> +class Hash_Map : + public ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, + ACE_Hash<EXT_ID>, ACE_Equal_To<EXT_ID>, ACE_Null_Mutex> +{}; + + +class Hash_Map_Example +{ +public: + ~Hash_Map_Example () + { + map_.close (); + } + + // illustrate the hash map + int run (void); + + // use the forward iterate + void iterate_forward (void); + + // use the reverse iterator + void iterate_reverse (void); + + // remove all the elements from the map + void remove_all (void); + +private: + Hash_Map<KeyType, DataElement> map_; +}; + +int Hash_Map_Example::run (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::run")); + + for (int i = 0; i < 100; i++) + { + map_.bind (i, DataElement (i)); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has \n"))); + for (int j = 0; j < 100; j++) + { + DataElement d; + map_.find (j, d); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Use the forward iterator. + this->iterate_forward (); + + // Use the reverse iterator. + this->iterate_reverse (); + + // Remove all the elements from the map. + this->remove_all (); + + // Iterate through the map again. + this->iterate_forward (); + + return 0; +} + +void Hash_Map_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration \n"))); + for (Hash_Map<KeyType, DataElement>::iterator iter = map_.begin (); + iter != map_.end (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Hash_Map_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::iterate_reverse")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration \n"))); + for (Hash_Map<KeyType, DataElement>::reverse_iterator iter = map_.rbegin (); + iter != map_.rend (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Hash_Map_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Hash_Map_Example::remove_all")); + map_.unbind_all (); +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Hash_Map_Example me; + return me.run (); +} + diff --git a/ACE/examples/APG/Containers/Hash_Map_Hash.h b/ACE/examples/APG/Containers/Hash_Map_Hash.h new file mode 100644 index 00000000000..a125f9ee7e6 --- /dev/null +++ b/ACE/examples/APG/Containers/Hash_Map_Hash.h @@ -0,0 +1,57 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef __HASH_MAP_HASH_H_ +#define __HASH_MAP_HASH_H_ + +// Listing 1 code/ch05 +// Key type that we are going to use. +class KeyType +{ +public: + KeyType () : val_(0) {} + + KeyType (int i) : val_(i) {} + + KeyType (const KeyType& kt) { this->val_ = kt.val_; } + + operator int (void) const { return val_; } + +private: + int val_; +}; + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Specialize the hash functor. +template<> +class ACE_Hash<KeyType> +{ +public: + u_long operator() (const KeyType kt) const + { + int val = kt; + return (u_long)val; + } +}; + + +// Specialize the equality functor. +template<> +class ACE_Equal_To<KeyType> +{ +public: + int operator() (const KeyType& kt1, + const KeyType& kt2) const + { + int val1 = kt1; + int val2 = kt2; + return (val1 == val2); + } +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Listing 1 + +#endif /* __HASH_MAP_HASH_H_ */ diff --git a/ACE/examples/APG/Containers/KeyType.h b/ACE/examples/APG/Containers/KeyType.h new file mode 100644 index 00000000000..268b56c1684 --- /dev/null +++ b/ACE/examples/APG/Containers/KeyType.h @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef __KEYTYPE_H_ +#define __KEYTYPE_H_ + +// Listing 1 code/ch05 +class KeyType +{ +public: + friend bool operator == (const KeyType&, const KeyType&); + + KeyType () : val_(0) {} + KeyType (int i) : val_(i) {} + KeyType (const KeyType& kt) { this->val_ = kt.val_; }; + operator int() const { return val_; }; + +private: + int val_; +}; + +bool operator == (const KeyType& a, const KeyType& b) +{ + return (a.val_ == b.val_); +} +// Listing 1 + +#endif /* __KEYTYPE_H_ */ diff --git a/ACE/examples/APG/Containers/Makefile.am b/ACE/examples/APG/Containers/Makefile.am new file mode 100644 index 00000000000..e5ef96ad6dc --- /dev/null +++ b/ACE/examples/APG/Containers/Makefile.am @@ -0,0 +1,223 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.Allocator.am +noinst_PROGRAMS = Allocator + +Allocator_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Allocator_SOURCES = \ + Allocator.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Allocator_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Array.am +noinst_PROGRAMS += Array + +Array_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Array_SOURCES = \ + Array.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Array_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Containers_Hash_Map.am +noinst_PROGRAMS += Hash_Map + +Hash_Map_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Hash_Map_SOURCES = \ + Hash_Map.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Hash_Map_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Containers_Map_Manager.am +noinst_PROGRAMS += Map_Manager + +Map_Manager_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Map_Manager_SOURCES = \ + Map_Manager.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Map_Manager_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.DLList.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += DLList + +DLList_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +DLList_SOURCES = \ + DLList.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +DLList_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Hash_Map_Hash.am +noinst_PROGRAMS += Hash_Map_Hash + +Hash_Map_Hash_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Hash_Map_Hash_SOURCES = \ + Hash_Map_Hash.cpp \ + Hash_Map_Hash.h + +Hash_Map_Hash_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Map_Manager_Specialization.am +noinst_PROGRAMS += Map_Manager_Specialization + +Map_Manager_Specialization_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Map_Manager_Specialization_SOURCES = \ + Map_Manager_Specialization.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Map_Manager_Specialization_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Queues.am +noinst_PROGRAMS += Queues + +Queues_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Queues_SOURCES = \ + Queues.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Queues_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.RB_Tree.am +noinst_PROGRAMS += RB_Tree + +RB_Tree_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +RB_Tree_SOURCES = \ + RB_Tree.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +RB_Tree_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.RB_Tree_Functors.am +noinst_PROGRAMS += RB_Tree_Functors + +RB_Tree_Functors_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +RB_Tree_Functors_SOURCES = \ + RB_Tree_Functors.cpp \ + RB_Tree_Functors.h + +RB_Tree_Functors_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sets.am +noinst_PROGRAMS += Sets + +Sets_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Sets_SOURCES = \ + Sets.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Sets_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Stacks.am +noinst_PROGRAMS += Stacks + +Stacks_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Stacks_SOURCES = \ + Stacks.cpp \ + DataElement.h \ + Hash_Map_Hash.h \ + KeyType.h \ + RB_Tree_Functors.h + +Stacks_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Containers/Map_Manager.cpp b/ACE/examples/APG/Containers/Map_Manager.cpp new file mode 100644 index 00000000000..6673204fcc4 --- /dev/null +++ b/ACE/examples/APG/Containers/Map_Manager.cpp @@ -0,0 +1,117 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Map_Manager.h" +#include "ace/Synch.h" +#include "DataElement.h" +#include "KeyType.h" + +class Map_Example +{ +public: + // Illustrate the ACE_Map_Manager. + int run (void); + +private: + // Iterate in the forward direction. + void iterate_forward (void); + + // Iterate in the other direction. + void iterate_reverse (void); + + // Remove all elements from the map. + void remove_all (void); + +private: + ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex> map_; +}; + +// Listing 2 code/ch05 +int Map_Example::run (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::run")); + + // Corresponding KeyType objects are created on the fly. + for (int i = 0; i < 100; i++) + { + map_.bind (i, DataElement (i)); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has \n"))); + for (int j = 0; j < 100; j++) + { + DataElement d; + map_.find (j,d); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Iterate in the forward direction. + this->iterate_forward (); + + // Iterate in the other direction. + this->iterate_reverse (); + + // Remove all elements from the map. + this->remove_all (); + + // Iterate in the forward direction. + this->iterate_forward (); + + return 0; +} +// Listing 2 +// Listing 3 code/ch05 +void Map_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); + for (ACE_Map_Manager<KeyType, + DataElement, + ACE_Null_Mutex>::iterator + iter = map_.begin (); + iter != map_.end (); + iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), + (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + + +void Map_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::iterate_reverse")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse iteration\n"))); + for (ACE_Map_Manager<KeyType, + DataElement, + ACE_Null_Mutex>::reverse_iterator + iter = map_.rbegin (); + iter != map_.end (); + iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), + (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} +// Listing 3 +// Listing 4 code/ch05 +void Map_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::remove_all")); + + // Note that we can't use the iterators here as they + // are invalidated after deletions or insertions. + map_.unbind_all (); +} +// Listing 4 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Map_Example me; + return me.run (); +} + diff --git a/ACE/examples/APG/Containers/Map_Manager_Specialization.cpp b/ACE/examples/APG/Containers/Map_Manager_Specialization.cpp new file mode 100644 index 00000000000..fc9c00d86f0 --- /dev/null +++ b/ACE/examples/APG/Containers/Map_Manager_Specialization.cpp @@ -0,0 +1,153 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Map_Manager.h" +#include "ace/Synch.h" // Needed for the lock. +#include "DataElement.h" +#include "KeyType.h" + +/* +** This needs to stay in the book for 2nd printing, but is the same as +** what's in KeyType.h. +*/ +#if 0 +// Listing 1 code/ch05 +class KeyType +{ +public: + KeyType () : val_(0) {} + + KeyType (int i) : val_(i) {} + + KeyType (const KeyType& kt) { this->val_ = kt.val_; }; + + operator int () const { return val_; }; + +private: + int val_; +}; + +template<> +int +ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::equal +(const KeyType& r1, const KeyType &r2) +{ + return (r1 == r2); +} +// Listing 1 +#else +template<> +int +ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::equal +(const KeyType& r1, const KeyType &r2) +{ + return (r1 == r2); +} +#endif /* 0 */ + +class Map_Example +{ +public: + // Illustrate the ACE_Map_Manager<>. + int run (void); + +private: + // Iterate in the forward direction. + void iterate_forward (void); + + // Iterate in the other direction. + void iterate_reverse (void); + + // Remove all elements from the map. + void remove_all (void); + +private: + ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex> map_; +}; + +int Map_Example::run (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::run")); + + // Corresponding KeyType objects are created on the fly. + for (int i = 0; i < 100; i++) + { + map_.bind (i, DataElement (i)); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has \n"))); + for (int j = 0; j < 100; j++) + { + DataElement d; + int result = map_.find (j,d); + if (result == 0) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); + } + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Iterate in the forward direction. + this->iterate_forward (); + + // Iterate in the other direction. + this->iterate_reverse (); + + // Remove all elements from the map. + this->remove_all (); + + // Iterate in the forward direction. + this->iterate_forward (); + + return 0; +} + +void Map_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); + for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::iterator + iter = map_.begin (); + iter!= map_.end (); + iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Map_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::iterate_reverse")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse iteration\n"))); + for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::reverse_iterator + iter = map_.rbegin (); + iter!= map_.end (); + iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Map_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Map_Example::remove_all")); + + // Note that we can't use the iterators here + // as they are invalidated after deletions + // or insertions. + for (int i = 0; i < 100; i++) + { + map_.unbind (i); + } +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Map_Example me; + return me.run (); +} + diff --git a/ACE/examples/APG/Containers/Queues.cpp b/ACE/examples/APG/Containers/Queues.cpp new file mode 100644 index 00000000000..ca945169ed4 --- /dev/null +++ b/ACE/examples/APG/Containers/Queues.cpp @@ -0,0 +1,115 @@ +// $Id$ + +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" +#include "ace/Containers.h" +#include "DataElement.h" + +class QueueExample +{ +public: + // Illustrate the various ACE Queues. + int run (void); + +private: + // Illustrate the ACE unbounded queue + // that has copies of the data elements. + int runStackUnboundedQueue (void); + + // Illustrate the ACE unbounded queue + // with pointers to elements on the heap. + int runHeapUnboundedQueue (void); +}; + +int QueueExample::run (void) +{ + ACE_TRACE (ACE_TEXT ("QueueExample::run")); + + // Illustrate the queue with elements on the stack. + if (this->runStackUnboundedQueue () != 0) + { + return -1; + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + // Illustrate the queue with elements on the heap. + if (this->runHeapUnboundedQueue () != 0) + { + return -1; + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + return 0; +} + +// Listing 1 code/ch05 +int QueueExample::runStackUnboundedQueue (void) +{ + ACE_TRACE (ACE_TEXT ("QueueExample::runStackUnboundedQueue")); + + ACE_Unbounded_Queue<DataElement> queue; + DataElement elem1[10]; + int i; + for (i = 0; i < 10; i++) + { + elem1[i].setData (9-i); + queue.enqueue_head (elem1[i]); + } + + DataElement elem2[10]; + for (i = 0; i < 10; i++) + { + elem2[i].setData (i+10); + queue.enqueue_tail (elem2[i]); + } + + for (ACE_Unbounded_Queue_Iterator<DataElement> iter (queue); + !iter.done (); + iter.advance ()) + { + DataElement *elem = 0; + iter.next (elem); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); + } + + return 0; +} +// Listing 1 +// Listing 2 code/ch05 +int QueueExample::runHeapUnboundedQueue (void) +{ + ACE_TRACE (ACE_TEXT ("QueueExample::runHeapUnboundedQueue")); + + ACE_Unbounded_Queue<DataElement*> queue; + for (int i = 0; i < 20; i++) + { + DataElement *elem; + ACE_NEW_RETURN(elem, DataElement (i), -1); + queue.enqueue_head (elem); + } + + for (ACE_Unbounded_Queue_Iterator<DataElement*> iter + = queue.begin (); + !iter.done (); + iter.advance ()) + { + DataElement **elem = 0; + iter.next(elem); + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("%d:"), (*elem)->getData ())); + delete (*elem); + } + + return 0; +} +// Listing 2 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + QueueExample que; + return que.run (); +} + diff --git a/ACE/examples/APG/Containers/RB_Tree.cpp b/ACE/examples/APG/Containers/RB_Tree.cpp new file mode 100644 index 00000000000..187332a31d8 --- /dev/null +++ b/ACE/examples/APG/Containers/RB_Tree.cpp @@ -0,0 +1,135 @@ +// $Id$ + +#include "ace/RB_Tree.h" +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "DataElement.h" + +// Little helper class. +template<class EXT_ID, class INT_ID> +class Tree : public ACE_RB_Tree<EXT_ID, INT_ID, + ACE_Less_Than<EXT_ID>, + ACE_Null_Mutex> +{}; + +class Tree_Example +{ +public: + // Illustrate the tree. + int run (void); + +private: + // Use the forward iterator. + void iterate_forward (void); + + // Use the reverse iterator. + void iterate_reverse (void); + + // Remove all elements from the tree. + int remove_all (void); + +private: + Tree<int, DataElement*> tree_; +}; + +// Listing 1 code/ch05 +int Tree_Example::run (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::run")); + + DataElement *d = 0; + for (int i = 0; i < 100; i++) + { + ACE_NEW_RETURN (d, DataElement (i), -1); + int result = tree_.bind (i, d); + if (result!= 0) + { + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Bind")), + -1); + } + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using find: \n"))); + for (int j = 0; j < 100; j++) + { + tree_.find (j, d); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Use the forward iterator. + this->iterate_forward (); + + // Use the reverse iterator. + this->iterate_reverse (); + + // Remove all elements from the tree. + ACE_ASSERT (this->remove_all ()!= -1); + + // Iterate through once again. + this->iterate_forward (); + + return 0; +} + +void Tree_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration: \n"))); + for (Tree<int, DataElement*>::iterator iter = tree_.begin (); + iter != tree_.end (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), + (*iter).item ()->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Tree_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::iterate_reverse")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration: \n"))); + for (Tree<int, DataElement*>::reverse_iterator iter + = tree_.rbegin (); + iter != tree_.rend (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), + (*iter).item ()->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +int Tree_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::remove_all")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Removing elements\n"))); + + // Note that we can't use the iterators here as they are + // invalidated after deletions or insertions. + for (int i = 0; i < 100; i++) + { + DataElement * d = 0; + int result = tree_.unbind (i, d); + if (result != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Unbind")), + -1); + } + ACE_ASSERT (d!= 0); + delete d; + } + + return 0; +} +// Listing 1 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Tree_Example te; + return te.run (); +} + diff --git a/ACE/examples/APG/Containers/RB_Tree_Functors.cpp b/ACE/examples/APG/Containers/RB_Tree_Functors.cpp new file mode 100644 index 00000000000..cb71fd75d79 --- /dev/null +++ b/ACE/examples/APG/Containers/RB_Tree_Functors.cpp @@ -0,0 +1,134 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "DataElement.h" +#include "RB_Tree_Functors.h" + +// Listing 0 code/ch05 +#include "ace/RB_Tree.h" +#include "ace/Synch.h" + +// Little helper class. +template<class EXT_ID, class INT_ID> +class Tree : public ACE_RB_Tree<EXT_ID, INT_ID, + ACE_Less_Than<EXT_ID>, + ACE_Null_Mutex> +{}; +// Listing 0 + +class Tree_Example +{ +public: + // Illustrate the tree. + int run (void); + +private: + // Use the forward iterator. + void iterate_forward (void); + + // Use the reverse iterator. + void iterate_reverse (void); + + // Remove all elements from the tree. + int remove_all (void); + +private: + Tree<KeyType, DataElement*> tree_; +}; + + +int Tree_Example::run () +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::run")); + + DataElement *d = 0; + for (int i = 0; i < 100; i++) + { + ACE_NEW_RETURN (d, DataElement (i), -1); + int result = tree_.bind(i, d); + if (result != 0) + { + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Bind"), -1); + } + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using find: \n"))); + for (int j = 0; j < 100; j++) + { + DataElement* d = 0; + int result = tree_.find (j, d); + if (result != 0) + { + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Find"), -1); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + + // Use the forward iterator. + this->iterate_forward (); + + // Use the reverse iterator. + this->iterate_reverse (); + + // Remove all elements from the tree. + ACE_ASSERT (this->remove_all ()!= -1); + + // Iterate through once again. + this->iterate_forward (); + + return 0; +} + +void Tree_Example::iterate_forward (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::iterate_forward")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration \n"))); + for (Tree<KeyType, DataElement*>::iterator iter = tree_.begin (); + iter != tree_.end (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +void Tree_Example::iterate_reverse (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::iterate_reverse")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration \n"))); + for (Tree<KeyType, DataElement*>::reverse_iterator iter = tree_.rbegin (); + iter != tree_.rend (); iter++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +} + +int Tree_Example::remove_all (void) +{ + ACE_TRACE (ACE_TEXT ("Tree_Example::remove_all")); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Removing elements\n"))); + for (int i = 0; i < 100; i++) + { + DataElement * d = 0; + int result = tree_.unbind (i, d); + if (result != 0) + { + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Unbind"), -1); + } + ACE_ASSERT (d != 0); + delete d; + } + + return 0; +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Tree_Example te; + return te.run (); +} + diff --git a/ACE/examples/APG/Containers/RB_Tree_Functors.h b/ACE/examples/APG/Containers/RB_Tree_Functors.h new file mode 100644 index 00000000000..010fb5fda62 --- /dev/null +++ b/ACE/examples/APG/Containers/RB_Tree_Functors.h @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef __RB_TREE_FUNCTORS_H_ +#define __RB_TREE_FUNCTORS_H_ + +#include "ace/Functor.h" + +// Listing 1 code/ch05 +// Same key type. +class KeyType +{ +public: + KeyType () : val_(0) {} + KeyType (int i) : val_ (i) {} + KeyType (const KeyType& kt) { this->val_ = kt.val_; } + operator int() const { return val_; }; + +private: + int val_; +}; + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template<> +class ACE_Less_Than<KeyType> +{ +public: + int operator() (const KeyType k1, const KeyType k2) + { return k1 < k2; } +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Listing 1 + +#endif /* __RB_TREE_FUNCTORS_H_ */ diff --git a/ACE/examples/APG/Containers/Sets.cpp b/ACE/examples/APG/Containers/Sets.cpp new file mode 100644 index 00000000000..3eaec6f7bec --- /dev/null +++ b/ACE/examples/APG/Containers/Sets.cpp @@ -0,0 +1,123 @@ +// $Id$ + +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" +#include "ace/Containers.h" +#include "DataElement.h" + +class SetExample +{ +public: + // Illustrate all ACE set types. + int run (void); + +private: + // Illustrate the ACE Bounded Sets. + int runBoundedSet (void); + + // Illustrate the ACE Unbounded sets. + int runUnboundedSet (void); +}; + +int SetExample::run (void) +{ + ACE_TRACE (ACE_TEXT ("SetExample::run")); + + ACE_ASSERT (!this->runBoundedSet ()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + ACE_ASSERT (!this->runUnboundedSet ()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects ())); + + return 0; +} +// Listing 1 code/ch05 +int SetExample::runBoundedSet () +{ + ACE_TRACE (ACE_TEXT ("SetExample::runBoundedSet")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a bounded set\n"))); + ACE_Bounded_Set<DataElement> bset (100); + + DataElement elem[100]; + for (int i = 0; i < 100; i++) + { + elem[i].setData (i); + + // Inserting two copies of the same element isn't allowed. + bset.insert (elem[i]); + if (bset.insert (elem[i]) == -1) + { + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("insert set"))); + } + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d\n"), + DataElement::numOfActiveObjects ())); + + DataElement elem1 (10), elem2 (99); + if (!bset.find (elem1) && !bset.find (elem2)) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("The elements %d and %d are ") + ACE_TEXT ("in the set!\n"), + elem1.getData (), elem2.getData ())); + } + + for (int j = 0; j < 50; j++) + { + bset.remove (elem[j]); // Remove the element from the set. + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("%d:"), elem[j].getData ())); + } + + if ((bset.find (elem[0]) == -1) && (bset.find (elem[49]) == -1)) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("The elements %d and %d are ") + ACE_TEXT ("NOT in the set!\n"), + elem[0].getData (), elem[99].getData ())); + } + + return 0; +} +// Listing 1 +// Listing 2 code/ch05 +int SetExample::runUnboundedSet () +{ + ACE_TRACE (ACE_TEXT ("SetExample::runUnboundedSet")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded set.\n"))); + ACE_Unbounded_Set<DataElement*> uset; + for (int m = 0; m < 100; m++) + { + DataElement *elem; + ACE_NEW_RETURN (elem, DataElement (m), -1); + uset.insert (elem); + } + DataElement deBegin (0), deEnd (99); + if (!uset.find (&deBegin) && !uset.find (&deEnd)) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Found the elements\n"))); + } + + // Iterate and destroy the elements in the set. + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Deleting the elements\n"))); + ACE_Unbounded_Set_Iterator<DataElement*> iter (uset); + for (iter = uset.begin (); iter != uset.end (); iter++) + { + DataElement* elem = (*iter); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); + delete elem; + } + + return 0; +} +// Listing 2 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + SetExample se; + se.run (); + return 0; +} diff --git a/ACE/examples/APG/Containers/Stacks.cpp b/ACE/examples/APG/Containers/Stacks.cpp new file mode 100644 index 00000000000..b02a243ab92 --- /dev/null +++ b/ACE/examples/APG/Containers/Stacks.cpp @@ -0,0 +1,147 @@ +// $Id$ + +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" +#include "ace/Containers.h" +#include "DataElement.h" + +class StackExample +{ +public: + StackExample (): privateStack_(100) {} + + // Illustrate all the differnet + // types of stacks provided by ACE. + int run (void); + +private: + // Illustrate the use of a bounded stack. + int runBoundedStack (void); + + // Illustrate the use of an unbounded stack. + int runUnboundedStack (void); + + // Illustrate the use of a compile time fixed stack. + int runFixedStack (void); + +private: + ACE_Bounded_Stack<DataElement*> privateStack_; +}; + +int StackExample::run (void) +{ + ACE_TRACE (ACE_TEXT ("StackUser::run")); + + ACE_ASSERT(!this->runBoundedStack()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects())); + + ACE_ASSERT(!this->runFixedStack()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects())); + + ACE_ASSERT(!this->runUnboundedStack()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), + DataElement::numOfActiveObjects())); + + return 0; +} +// Listing 1 code/ch05 +int StackExample::runBoundedStack (void) +{ + ACE_TRACE (ACE_TEXT ("StackExample::runBoundedStack")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a bounded stack\n"))); + + ACE_Bounded_Stack<DataElement> bstack1 (100); + + // The element array is constrained to this scope. + { + DataElement elem[100]; + for (int i = 0; i < 100; i++) + { + elem[i].setData(i); + // Push the element on the stack. + bstack1.push (elem[i]); + } + } + + ACE_Bounded_Stack<DataElement> bstack2 (100); + + // Make a copy! + bstack2 = bstack1; + for (int j = 0; j < 100; j++) + { + DataElement elem; + bstack2.pop (elem); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem.getData ())); + } + + return 0; +} +// Listing 1 +// Listing 2 code/ch05 +int StackExample::runFixedStack (void) +{ + ACE_TRACE (ACE_TEXT ("StackExample::runFixedStack")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a fixed stack\n"))); + + ACE_Fixed_Stack<DataElement*, 100> fstack; + for (int k = 0; k < 100; k++) + { + DataElement* elem; + ACE_NEW_RETURN(elem, DataElement (k), -1); + fstack.push (elem); // Push the element on the stack. + } + + for (int l = 0; l < 100; l++) + { + DataElement* elem = 0; + fstack.pop (elem); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); + delete elem; + } + + return 0; +} + +int StackExample::runUnboundedStack (void) +{ + ACE_TRACE (ACE_TEXT ("StackExample::runUnboundedStack")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded stack\n"))); + + ACE_Unbounded_Stack<DataElement*> ustack; + for (int m = 0; m < 100; m++) + { + DataElement *elem; + ACE_NEW_RETURN(elem, DataElement (m), -1); + // Push the element on both stacks. + ustack.push (elem); + privateStack_.push (elem); + } + + // Oddly enough, you can actually iterate through an + // unbounded stack! This is because underneath the covers + // the unbounded stack is a linked list. + + // This will cause the elements in the private stack to + // also disappear! + ACE_Unbounded_Stack_Iterator<DataElement*> iter (ustack); + for (iter.first (); !iter.done (); iter.advance ()) + { + DataElement** elem = 0; + iter.next (elem); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), + (*elem)->getData ())); + delete (*elem); + } + + return 0; +} +// Listing 2 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + StackExample se; + return se.run (); +} + diff --git a/ACE/examples/APG/Containers/containers.mpc b/ACE/examples/APG/Containers/containers.mpc new file mode 100644 index 00000000000..d08ef9133aa --- /dev/null +++ b/ACE/examples/APG/Containers/containers.mpc @@ -0,0 +1,87 @@ +// -*- MPC -*- +// $Id$ + +project(DLList) : aceexe { + avoids += ace_for_tao + exename = DLList + Source_Files { + DLList.cpp + } +} + +project(Stacks) : aceexe { + exename = Stacks + Source_Files { + Stacks.cpp + } +} + +project(Queues) : aceexe { + exename = Queues + Source_Files { + Queues.cpp + } +} + +project(Array) : aceexe { + exename = Array + Source_Files { + Array.cpp + } +} + +project(Sets) : aceexe { + exename = Sets + Source_Files { + Sets.cpp + } +} + +project(*Map Manager) : aceexe { + exename = Map_Manager + Source_Files { + Map_Manager.cpp + } +} + +project(Map Manager Specialization) : aceexe { + exename = Map_Manager_Specialization + Source_Files { + Map_Manager_Specialization.cpp + } +} + +project(*Hash Map) : aceexe { + exename = Hash_Map + Source_Files { + Hash_Map.cpp + } +} + +project(Hash Map Hash) : aceexe { + exename = Hash_Map_Hash + Source_Files { + Hash_Map_Hash.cpp + } +} + +project(RB Tree) : aceexe { + exename = RB_Tree + Source_Files { + RB_Tree.cpp + } +} + +project(RB Tree Functors) : aceexe { + exename = RB_Tree_Functors + Source_Files { + RB_Tree_Functors.cpp + } +} + +project(Allocator) : aceexe { + exename = Allocator + Source_Files { + Allocator.cpp + } +} diff --git a/ACE/examples/APG/Logging/.cvsignore b/ACE/examples/APG/Logging/.cvsignore new file mode 100644 index 00000000000..821ee0bc87c --- /dev/null +++ b/ACE/examples/APG/Logging/.cvsignore @@ -0,0 +1,36 @@ +Change_Instance_Default +Change_Instance_Default +Change_Mask +Change_Mask +Howto_Syslog +Howto_Syslog +Simple1 +Simple1 +Simple2 +Simple2 +Trace_Return +Trace_Return +Use_Callback +Use_Callback +Use_Callback2 +Use_Callback2 +Use_LogManager +Use_LogManager +Use_Logger +Use_Logger +Use_Logging_Server +Use_Logging_Server +Use_Logging_Strategy +Use_Logging_Strategy +Use_Multiple_Sinks +Use_Multiple_Sinks +Use_Ostream +Use_Ostream +Use_Stderr +Use_Stderr +Use_Syslog +Use_Syslog +Wrap_Macros +Wrap_Macros +Wrap_Macros_Alt +Wrap_Macros_Alt diff --git a/ACE/examples/APG/Logging/Callback-2.h b/ACE/examples/APG/Logging/Callback-2.h new file mode 100644 index 00000000000..906b2e43286 --- /dev/null +++ b/ACE/examples/APG/Logging/Callback-2.h @@ -0,0 +1,44 @@ +// $Id$ + +#ifndef APG_CALLBACK2_H +#define APG_CALLBACK2_H + +#include "ace/OS_NS_time.h" +#include "ace/streams.h" +#include "ace/Log_Msg_Callback.h" +#include "ace/Log_Record.h" +#include "ace/SString.h" +#include "ace/Time_Value.h" + +class Callback : public ACE_Log_Msg_Callback +{ +public: + void log (ACE_Log_Record &log_record) + { + cerr << "Log Message Received:" << endl; + unsigned long msg_severity = log_record.type (); + ACE_Log_Priority prio = + static_cast<ACE_Log_Priority> (msg_severity); + const ACE_TCHAR *prio_name = + ACE_Log_Record::priority_name (prio); + cerr << "\tType: " + << ACE_TEXT_ALWAYS_CHAR (prio_name) + << endl; + + cerr << "\tLength: " << log_record.length () << endl; + + const time_t epoch = log_record.time_stamp ().sec (); + cerr << "\tTime_Stamp: " + << ACE_TEXT_ALWAYS_CHAR (ACE_OS::ctime (&epoch)) + << flush; + + cerr << "\tPid: " << log_record.pid () << endl; + + ACE_CString data (">> "); + data += ACE_TEXT_ALWAYS_CHAR (log_record.msg_data ()); + + cerr << "\tMsgData: " << data.c_str () << endl; + } +}; + +#endif /* APG_CALLBACK2_H */ diff --git a/ACE/examples/APG/Logging/Callback-3.h b/ACE/examples/APG/Logging/Callback-3.h new file mode 100644 index 00000000000..22824fad382 --- /dev/null +++ b/ACE/examples/APG/Logging/Callback-3.h @@ -0,0 +1,69 @@ +// $Id$ + +#ifndef APG_CALLBACK3_H +#define APG_CALLBACK3_H + +#include "ace/streams.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Msg_Callback.h" +#include "ace/Log_Record.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Connector.h" +#include "ace/INET_Addr.h" + +#define LOGGER_PORT 20009 + +class Callback : public ACE_Log_Msg_Callback +{ +public: + Callback () + { + this->logger_ = new ACE_SOCK_Stream; + ACE_SOCK_Connector connector; + ACE_INET_Addr addr (LOGGER_PORT, ACE_DEFAULT_SERVER_HOST); + + if (connector.connect (*(this->logger_), addr) == -1) + { + delete this->logger_; + this->logger_ = 0; + } + } + + virtual ~Callback () + { + if (this->logger_) + { + this->logger_->close (); + } + delete this->logger_; + } + + void log (ACE_Log_Record &log_record) + { + if (!this->logger_) + { +# if defined (ACE_LACKS_IOSTREAM_TOTALLY) + log_record.print + (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, stderr); +# else + log_record.print + (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, cerr); +# endif /* ACE_LACKS_IOSTREAM_TOTALLY */ + return; + } + + size_t len = log_record.length(); + log_record.encode (); + + if (this->logger_->send_n ((char *) &log_record, len) == -1) + { + delete this->logger_; + this->logger_ = 0; + } + } + +private: + ACE_SOCK_Stream *logger_; +}; + +#endif /* APG_CALLBACK3_H */ diff --git a/ACE/examples/APG/Logging/Callback.h b/ACE/examples/APG/Logging/Callback.h new file mode 100644 index 00000000000..86dff9ea826 --- /dev/null +++ b/ACE/examples/APG/Logging/Callback.h @@ -0,0 +1,25 @@ +// $Id$ + +#ifndef APG_CALLBACK_H +#define APG_CALLBACK_H + +#include "ace/streams.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Msg_Callback.h" +#include "ace/Log_Record.h" + +class Callback : public ACE_Log_Msg_Callback +{ +public: + void log (ACE_Log_Record &log_record) { +# if defined (ACE_LACKS_IOSTREAM_TOTALLY) + log_record.print (ACE_TEXT (""), 0, stderr); + log_record.print (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, stderr); +# else + log_record.print (ACE_TEXT (""), 0, cerr); + log_record.print (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, cerr); +# endif /* ACE_LACKS_IOSTREAM_TOTALLY */ + } +}; + +#endif /* APG_CALLBACK_H */ diff --git a/ACE/examples/APG/Logging/Change_Instance_Default.cpp b/ACE/examples/APG/Logging/Change_Instance_Default.cpp new file mode 100644 index 00000000000..e22af840259 --- /dev/null +++ b/ACE/examples/APG/Logging/Change_Instance_Default.cpp @@ -0,0 +1,37 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + * + * This code shows how to set the ACE_Log_Msg per-instance default + * differently for groups of spawned threads. + */ + +#include "ace/Log_Msg.h" +#include "ace/Thread_Manager.h" + +ACE_THR_FUNC_RETURN worker (void *) +{ + // do some work + return 0; +} + +ACE_THR_FUNC_RETURN service (void *) +{ + // run the service + return 0; +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 1 code/ch03 + ACE_LOG_MSG->priority_mask (0, ACE_Log_Msg::PROCESS); + ACE_Log_Msg::enable_debug_messages (); + ACE_Thread_Manager::instance ()->spawn (service); + ACE_Log_Msg::disable_debug_messages (); + ACE_Thread_Manager::instance ()->spawn_n (3, worker); + // Listing 1 + ACE_Thread_Manager::instance ()->wait (); + return 0; +} diff --git a/ACE/examples/APG/Logging/Change_Mask.cpp b/ACE/examples/APG/Logging/Change_Mask.cpp new file mode 100644 index 00000000000..a34a00e63b1 --- /dev/null +++ b/ACE/examples/APG/Logging/Change_Mask.cpp @@ -0,0 +1,29 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("main"); + + // Listing 1 code/ch03 + ACE_LOG_MSG->priority_mask (0, ACE_Log_Msg::PROCESS); + ACE_LOG_MSG->priority_mask (LM_DEBUG | LM_NOTICE, + ACE_Log_Msg::THREAD); + // Listing 1 + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n"))); + foo (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_NOTICE, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Howto_Syslog.cpp b/ACE/examples/APG/Logging/Howto_Syslog.cpp new file mode 100644 index 00000000000..283099a3da1 --- /dev/null +++ b/ACE/examples/APG/Logging/Howto_Syslog.cpp @@ -0,0 +1,28 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo (void); + +// Listing 1 code/ch03 +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + ACE_LOG_MSG->open + (argv[0], ACE_Log_Msg::SYSLOG, ACE_TEXT ("syslogTest")); + // Listing 1 + + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + foo (); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/LogManager.h b/ACE/examples/APG/Logging/LogManager.h new file mode 100644 index 00000000000..2cf8c7f7d48 --- /dev/null +++ b/ACE/examples/APG/Logging/LogManager.h @@ -0,0 +1,102 @@ +// $Id$ + +#include "ace/streams.h" +#include "ace/Synch.h" +#include "ace/Singleton.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Msg_Callback.h" + +#ifndef LOG_MANAGER_H +#define LOG_MANAGER_H + +// Listing 1 code/ch03 +class LogManager +{ +public: + LogManager (); + ~LogManager (); + + void redirectToDaemon + (const ACE_TCHAR *prog_name = ACE_TEXT ("")); + void redirectToSyslog + (const ACE_TCHAR *prog_name = ACE_TEXT ("")); + void redirectToOStream (ACE_OSTREAM_TYPE *output); + void redirectToFile (const char *filename); + void redirectToStderr (void); + ACE_Log_Msg_Callback * redirectToCallback + (ACE_Log_Msg_Callback *callback); + + // Exclude 1 +private: + ofstream *log_stream_; + ACE_OSTREAM_TYPE *output_stream_; + // Exclude 1 +}; +// Listing 1 + +// Listing 2 code/ch03 +LogManager::LogManager () + : log_stream_ (0), output_stream_ (0) +{ } + +LogManager::~LogManager () +{ + if (log_stream_) + log_stream_->close (); + delete log_stream_; +} + +void LogManager::redirectToSyslog (const ACE_TCHAR *prog_name) +{ + ACE_LOG_MSG->open (prog_name, ACE_Log_Msg::SYSLOG, prog_name); +} + +void LogManager::redirectToDaemon (const ACE_TCHAR *prog_name) +{ + ACE_LOG_MSG->open (prog_name, ACE_Log_Msg::LOGGER, + ACE_DEFAULT_LOGGER_KEY); +} + +void LogManager::redirectToOStream (ACE_OSTREAM_TYPE *output) +{ + output_stream_ = output; + ACE_LOG_MSG->msg_ostream (this->output_stream_); + ACE_LOG_MSG->clr_flags + (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); +} + +void LogManager::redirectToFile (const char *filename) +{ + log_stream_ = new ofstream (); + log_stream_->open (filename, ios::out | ios::app); + this->redirectToOStream ((ACE_OSTREAM_TYPE *)log_stream_); +} + +void LogManager::redirectToStderr (void) +{ + ACE_LOG_MSG->clr_flags + (ACE_Log_Msg::OSTREAM | ACE_Log_Msg::LOGGER); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR); +} + +ACE_Log_Msg_Callback * +LogManager::redirectToCallback (ACE_Log_Msg_Callback * callback) +{ + ACE_Log_Msg_Callback *previous = + ACE_LOG_MSG->msg_callback (callback); + if (callback == 0) + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::MSG_CALLBACK); + else + ACE_LOG_MSG->set_flags (ACE_Log_Msg::MSG_CALLBACK); + return previous; +} +// Listing 2 + +// Listing 3 code/ch03 +typedef ACE_Singleton<LogManager, ACE_Null_Mutex> + LogManagerSingleton; +#define LOG_MANAGER LogManagerSingleton::instance() +// Listing 3 + +#endif /* LOG_MANAGER_H */ diff --git a/ACE/examples/APG/Logging/Log_Msg_Alt.h b/ACE/examples/APG/Logging/Log_Msg_Alt.h new file mode 100644 index 00000000000..c78d2bd1f4a --- /dev/null +++ b/ACE/examples/APG/Logging/Log_Msg_Alt.h @@ -0,0 +1,19 @@ +// $Id$ + +#ifndef LOG_MSG_ALT_H +#define LOG_MSG_ALT_H + +#include "ace/Log_Msg.h" + +// Listing 1 code/ch03 +#define MY_DEBUG LM_DEBUG, ACE_TEXT ("DEBUG%I") +#define MY_INFO LM_INFO, ACE_TEXT ("INFO%I") +#define MY_NOTICE LM_NOTICE, ACE_TEXT ("NOTICE%I") +#define MY_WARNING LM_WARNING, ACE_TEXT ("WARNING%I") +#define MY_ERROR LM_ERROR, ACE_TEXT ("ERROR%I") +#define MY_CRITICAL LM_CRITICAL, ACE_TEXT ("CRITICAL%I") +#define MY_ALERT LM_ALERT, ACE_TEXT ("ALERT%I") +#define MY_EMERGENCY LM_EMERGENCY, ACE_TEXT ("EMERGENCY%I") +// Listing 1 + +#endif /* LOG_ALT_H */ diff --git a/ACE/examples/APG/Logging/Makefile.am b/ACE/examples/APG/Logging/Makefile.am new file mode 100644 index 00000000000..69564edb197 --- /dev/null +++ b/ACE/examples/APG/Logging/Makefile.am @@ -0,0 +1,362 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Change_Instance_Default.am +noinst_PROGRAMS = Change_Instance_Default + +Change_Instance_Default_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Change_Instance_Default_SOURCES = \ + Change_Instance_Default.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Change_Instance_Default_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Change_Mask.am +noinst_PROGRAMS += Change_Mask + +Change_Mask_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Change_Mask_SOURCES = \ + Change_Mask.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Change_Mask_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Howto_Syslog.am +noinst_PROGRAMS += Howto_Syslog + +Howto_Syslog_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Howto_Syslog_SOURCES = \ + Howto_Syslog.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Howto_Syslog_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Simple1.am +noinst_PROGRAMS += Simple1 + +Simple1_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Simple1_SOURCES = \ + Simple1.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Simple1_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Simple2.am +noinst_PROGRAMS += Simple2 + +Simple2_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Simple2_SOURCES = \ + Simple2.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Simple2_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Trace_Return.am +noinst_PROGRAMS += Trace_Return + +Trace_Return_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Trace_Return_SOURCES = \ + Trace_Return.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Trace_Return_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Callback.am +noinst_PROGRAMS += Use_Callback + +Use_Callback_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Callback_SOURCES = \ + Use_Callback.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Callback_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Callback2.am +noinst_PROGRAMS += Use_Callback2 + +Use_Callback2_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Callback2_SOURCES = \ + Use_Callback2.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Callback2_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_LogManager.am +noinst_PROGRAMS += Use_LogManager + +Use_LogManager_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_LogManager_SOURCES = \ + Use_LogManager.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_LogManager_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Logger.am +noinst_PROGRAMS += Use_Logger + +Use_Logger_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Logger_SOURCES = \ + Use_Logger.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Logger_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Logging_Server.am +noinst_PROGRAMS += Use_Logging_Server + +Use_Logging_Server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Logging_Server_SOURCES = \ + Use_Logging_Server.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Logging_Server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Logging_Strategy.am +noinst_PROGRAMS += Use_Logging_Strategy + +Use_Logging_Strategy_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Logging_Strategy_SOURCES = \ + Use_Logging_Strategy.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Logging_Strategy_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Multiple_Sinks.am +noinst_PROGRAMS += Use_Multiple_Sinks + +Use_Multiple_Sinks_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Multiple_Sinks_SOURCES = \ + Use_Multiple_Sinks.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Multiple_Sinks_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Ostream.am +noinst_PROGRAMS += Use_Ostream + +Use_Ostream_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Ostream_SOURCES = \ + Use_Ostream.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Ostream_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Stderr.am +noinst_PROGRAMS += Use_Stderr + +Use_Stderr_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Stderr_SOURCES = \ + Use_Stderr.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Stderr_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Use_Syslog.am +noinst_PROGRAMS += Use_Syslog + +Use_Syslog_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Use_Syslog_SOURCES = \ + Use_Syslog.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Use_Syslog_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Wrap_Macros.am +noinst_PROGRAMS += Wrap_Macros + +Wrap_Macros_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Wrap_Macros_SOURCES = \ + Wrap_Macros.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Wrap_Macros_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Wrap_Macros_Alt.am +noinst_PROGRAMS += Wrap_Macros_Alt + +Wrap_Macros_Alt_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Wrap_Macros_Alt_SOURCES = \ + Wrap_Macros_Alt.cpp \ + Callback-2.h \ + Callback-3.h \ + Callback.h \ + LogManager.h \ + Log_Msg_Alt.h \ + Trace.h + +Wrap_Macros_Alt_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Logging/Simple1.cpp b/ACE/examples/APG/Logging/Simple1.cpp new file mode 100644 index 00000000000..cf7a12e410b --- /dev/null +++ b/ACE/examples/APG/Logging/Simple1.cpp @@ -0,0 +1,23 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE("main"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n"))); + foo(); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Simple2.cpp b/ACE/examples/APG/Logging/Simple2.cpp new file mode 100644 index 00000000000..26315b9d689 --- /dev/null +++ b/ACE/examples/APG/Logging/Simple2.cpp @@ -0,0 +1,25 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo(void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("main"); + + ACE_LOG_MSG->priority_mask (LM_DEBUG | LM_NOTICE, + ACE_Log_Msg::PROCESS); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n"))); + foo (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo(void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_NOTICE, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Trace.h b/ACE/examples/APG/Logging/Trace.h new file mode 100644 index 00000000000..c7f40c343eb --- /dev/null +++ b/ACE/examples/APG/Logging/Trace.h @@ -0,0 +1,153 @@ +// $Id$ + +#ifndef TRACE_H +#define TRACE_H + +#include "ace/Log_Msg.h" + +// Listing 1 code/ch03 +class Trace +{ +public: + Trace (const ACE_TCHAR *prefix, + const ACE_TCHAR *name, + int line, + const ACE_TCHAR *file) + { + this->prefix_ = prefix; + this->name_ = name; + this->line_ = line; + this->file_ = file; + + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG + ((LM_TRACE, + ACE_TEXT ("%s%*s(%t) calling %s in file `%s'") + ACE_TEXT (" on line %d\n"), + this->prefix_, + Trace::nesting_indent_ * lm->inc (), + ACE_TEXT (""), + this->name_, + this->file_, + this->line_)); + lm->trace_active (0); + } + } + + void setLine (int line) + { + this->line_ = line; + } + + ~Trace (void) + { + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG + ((LM_TRACE, + ACE_TEXT ("%s%*s(%t) leaving %s in file `%s'") + ACE_TEXT (" on line %d\n"), + this->prefix_, + Trace::nesting_indent_ * lm->dec (), + ACE_TEXT (""), + this->name_, + this->file_, + this->line_)); + lm->trace_active (0); + } + } + +private: + enum { nesting_indent_ = 3 }; + + const ACE_TCHAR *prefix_; + const ACE_TCHAR *name_; + const ACE_TCHAR *file_; + int line_; +}; +// Listing 1 + +// Listing 2 code/ch03 +#define TRACE_PREFIX ACE_TEXT ("TRACE ") + +#if (ACE_NTRACE == 1) +# define TRACE(X) +# define TRACE_RETURN(V) return V; +# define TRACE_RETURN_VOID() +#else +# define TRACE(X) \ + Trace ____ (TRACE_PREFIX, \ + ACE_TEXT (X), \ + __LINE__, \ + ACE_TEXT (__FILE__)) + +# define TRACE_RETURN(V) \ + do { ____.setLine(__LINE__); return V; } while (0) + +# define TRACE_RETURN_VOID() \ + do { ____.setLine(__LINE__); } while (0) +#endif +// Listing 2 + +////////////////////////////////////////////////// + +#if defined (__GNUC__) && (__GNUC__ >= 3 || __GNUC_MINOR__ > 95) && \ + (!defined (VXWORKS) || !(__GNUC__ == 2 && __GNUC_MINOR__ == 96)) +// This stuff only works with g++ 2.96 and later... +// But not with VxWorks g++ 2.96. + +// Listing 3 code/ch03 + +#define DEBUG_PREFIX ACE_TEXT ("DEBUG%I") +#define INFO_PREFIX ACE_TEXT ("INFO%I") +#define NOTICE_PREFIX ACE_TEXT ("NOTICE%I") +#define WARNING_PREFIX ACE_TEXT ("WARNING%I") +#define ERROR_PREFIX ACE_TEXT ("ERROR%I") +#define CRITICAL_PREFIX ACE_TEXT ("CRITICAL%I") +#define ALERT_PREFIX ACE_TEXT ("ALERT%I") +#define EMERGENCY_PREFIX ACE_TEXT ("EMERGENCY%I") + +#define MY_DEBUG(FMT, ...) \ + ACE_DEBUG(( LM_DEBUG, \ + DEBUG_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_INFO(FMT, ...) \ + ACE_DEBUG(( LM_INFO, \ + INFO_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_NOTICE(FMT, ...) \ + ACE_DEBUG(( LM_NOTICE, \ + NOTICE_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_WARNING(FMT, ...) \ + ACE_DEBUG(( LM_WARNING, \ + WARNING_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_ERROR(FMT, ...) \ + ACE_DEBUG(( LM_ERROR, \ + ERROR_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_CRITICAL(FMT, ...) \ + ACE_DEBUG(( LM_CRITICAL, \ + CRITICAL_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_ALERT(FMT, ...) \ + ACE_DEBUG(( LM_ALERT, \ + ALERT_PREFIX FMT \ + ##__VA_ARGS__)) +#define MY_EMERGENCY(FMT, ...) \ + ACE_DEBUG(( LM_EMERGENCY, \ + EMERGENCY_PREFIX FMT \ + ##__VA_ARGS__)) +// Listing 3 + +#endif /* __GNUC__ */ + +#endif /* TRACE_H */ diff --git a/ACE/examples/APG/Logging/Trace_Return.cpp b/ACE/examples/APG/Logging/Trace_Return.cpp new file mode 100644 index 00000000000..1bb32a03456 --- /dev/null +++ b/ACE/examples/APG/Logging/Trace_Return.cpp @@ -0,0 +1,41 @@ +// $Id$ + +#include "Trace.h" + +#if defined (__GNUC__) && (__GNUC__ >= 3 || __GNUC_MINOR__ > 95) && \ + (!defined (VXWORKS) || !(__GNUC__ == 2 && __GNUC_MINOR__ == 96)) +// The DEBUG stuff only works with g++ 2.96 and later. +// But not with VxWorks g++ 2.96. + +// Listing 1 code/ch03 +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + TRACE ("main"); + + MY_DEBUG (ACE_TEXT ("Hi Mom\n")); + foo (); + MY_DEBUG (ACE_TEXT ("Goodnight\n")); + + TRACE_RETURN (0); +} + +void foo (void) +{ + TRACE ("foo"); + MY_DEBUG (ACE_TEXT ("Howdy Pardner\n")); + TRACE_RETURN_VOID (); +} +// Listing 1 + +#else +#include <stdio.h> + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + puts ("This example only works on g++ 2.96 and later.\n"); + return 0; +} + +#endif /* __GNUC__ */ diff --git a/ACE/examples/APG/Logging/Use_Callback.cpp b/ACE/examples/APG/Logging/Use_Callback.cpp new file mode 100644 index 00000000000..2f08a2127ed --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Callback.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "Callback.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Callback *callback = new Callback; + + ACE_LOG_MSG->set_flags (ACE_Log_Msg::MSG_CALLBACK); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); + ACE_LOG_MSG->msg_callback (callback); + + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} diff --git a/ACE/examples/APG/Logging/Use_Callback2.cpp b/ACE/examples/APG/Logging/Use_Callback2.cpp new file mode 100644 index 00000000000..bcfe8b8e5d7 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Callback2.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "Callback-2.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Callback *callback = new Callback; + + ACE_LOG_MSG->set_flags (ACE_Log_Msg::MSG_CALLBACK); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); + ACE_LOG_MSG->msg_callback (callback); + + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} diff --git a/ACE/examples/APG/Logging/Use_LogManager.cpp b/ACE/examples/APG/Logging/Use_LogManager.cpp new file mode 100644 index 00000000000..76de7b7fb56 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_LogManager.cpp @@ -0,0 +1,33 @@ +// $Id$ + +#include "LogManager.h" + +// Listing 1 code/ch03 +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + LOG_MANAGER->redirectToStderr (); + ACE_TRACE ("main"); + LOG_MANAGER->redirectToSyslog (); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n"))); + foo (); + LOG_MANAGER->redirectToDaemon (); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} +void foo (void) +{ + ACE_TRACE ("foo"); + LOG_MANAGER->redirectToFile ("output.test"); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} +// Listing 1 + +// Listing 2 code/ch03 +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<LogManager, ACE_Null_Mutex> * + ACE_Singleton<LogManager, ACE_Null_Mutex>::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ +// Listing 2 diff --git a/ACE/examples/APG/Logging/Use_Logger.cpp b/ACE/examples/APG/Logging/Use_Logger.cpp new file mode 100644 index 00000000000..5fb672c1ab4 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Logger.cpp @@ -0,0 +1,17 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + ACE_LOG_MSG->open (argv[0], + ACE_Log_Msg::LOGGER, + ACE_DEFAULT_LOGGER_KEY); + + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} diff --git a/ACE/examples/APG/Logging/Use_Logging_Server.cpp b/ACE/examples/APG/Logging/Use_Logging_Server.cpp new file mode 100644 index 00000000000..eaad6bf7a6b --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Logging_Server.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "Callback-3.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Callback *callback = new Callback; + + ACE_LOG_MSG->set_flags (ACE_Log_Msg::MSG_CALLBACK); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); + ACE_LOG_MSG->msg_callback (callback); + + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} diff --git a/ACE/examples/APG/Logging/Use_Logging_Strategy.cpp b/ACE/examples/APG/Logging/Use_Logging_Strategy.cpp new file mode 100644 index 00000000000..559d85d65ae --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Logging_Strategy.cpp @@ -0,0 +1,33 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" + +/* + Put the following in your svc.conf: + + dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-s log.out -f STDERR|OSTREAM -p DEBUG|NOTICE" + + There seems to be a bug in ACE_Logging_Strategy in that the priority + flags are not propagated to spawned threads. +*/ + +// Listing 1 code/ch03 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (ACE_Service_Config::open (argc, + argv, + ACE_DEFAULT_LOGGER_KEY, + 1, + 0, + 1) < 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Service Config open")), + 1); + ACE_TRACE ("main"); + ACE_DEBUG ((LM_NOTICE, ACE_TEXT ("%t%IHowdy Pardner\n"))); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%t%IGoodnight\n"))); + + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Logging/Use_Multiple_Sinks.cpp b/ACE/examples/APG/Logging/Use_Multiple_Sinks.cpp new file mode 100644 index 00000000000..352a598b4e2 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Multiple_Sinks.cpp @@ -0,0 +1,34 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/streams.h" + +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + // Output to default destination (stderr) + ACE_LOG_MSG->open (argv[0]); + + ACE_TRACE ("main"); + + ACE_OSTREAM_TYPE *output = + (ACE_OSTREAM_TYPE *) new ofstream ("ostream.output.test"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IThis will go to STDERR\n"))); + + ACE_LOG_MSG->open + (argv[0], ACE_Log_Msg::SYSLOG, ACE_TEXT ("syslogTest")); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR); + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("%IThis goes to STDERR & syslog\n"))); + + ACE_LOG_MSG->msg_ostream (output, 0); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%IThis will go to STDERR, ") + ACE_TEXT ("syslog & an ostream\n"))); + + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::OSTREAM); + delete output; + + return 0; +} diff --git a/ACE/examples/APG/Logging/Use_Ostream.cpp b/ACE/examples/APG/Logging/Use_Ostream.cpp new file mode 100644 index 00000000000..28a2fefcc1c --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Ostream.cpp @@ -0,0 +1,36 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/streams.h" + +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + + /* Alternatively, you can use the set_flags() method to do the same + thing after the singleton has been created: + */ + // Listing 2 code/ch03 + ACE_OSTREAM_TYPE *output = + (ACE_OSTREAM_TYPE *) new ofstream ("ostream.output.test"); + ACE_LOG_MSG->msg_ostream (output, 1); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); + // Listing 2 + + foo (); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Use_Stderr.cpp b/ACE/examples/APG/Logging/Use_Stderr.cpp new file mode 100644 index 00000000000..e0418c4d362 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Stderr.cpp @@ -0,0 +1,38 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo (void); + +// Listing 1 code/ch03 +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + // open() requires the name of the application + // (e.g. -- argv[0]) because the underlying + // implementation may use it in the log output. + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); + // Listing 1 + + /* Alternatively, you can use the set_flags() method to do the same + thing after the singleton has been created: + */ + + ACE_TRACE ("main"); + + // Listing 2 code/ch03 + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR); + foo (); + // Listing 2 + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Use_Syslog.cpp b/ACE/examples/APG/Logging/Use_Syslog.cpp new file mode 100644 index 00000000000..dce4a1fe6b0 --- /dev/null +++ b/ACE/examples/APG/Logging/Use_Syslog.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + // This will be directed to stderr (the default ACE_Log_Msg + // behavior). + ACE_TRACE ("main"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n"))); + + // Everything from foo() will be directed to the system logger + ACE_LOG_MSG->open + (argv[0], ACE_Log_Msg::SYSLOG, ACE_TEXT ("syslogTest")); + foo (); + + // Now we reset the log output to default (stderr) + ACE_LOG_MSG->open (argv[0]); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n"))); + + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n"))); +} diff --git a/ACE/examples/APG/Logging/Wrap_Macros.cpp b/ACE/examples/APG/Logging/Wrap_Macros.cpp new file mode 100644 index 00000000000..9e88d3e11e0 --- /dev/null +++ b/ACE/examples/APG/Logging/Wrap_Macros.cpp @@ -0,0 +1,38 @@ +// $Id$ + +#include "Trace.h" + +#if defined (__GNUC__) && (__GNUC__ >= 3 || __GNUC_MINOR__ > 95) && \ + (!defined (VXWORKS) || !(__GNUC__ == 2 && __GNUC_MINOR__ == 96)) +// The macros in Trace.h only work on g++ 2.96 and later. +// But not with VxWorks g++ 2.96. + +// Listing 1 code/ch03 +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("main"); + MY_DEBUG (ACE_TEXT ("Hi Mom\n")); + foo (); + MY_DEBUG (ACE_TEXT ("Goodnight\n")); + return 0; +} + +void foo (void) +{ + ACE_TRACE ("foo"); + MY_DEBUG (ACE_TEXT ("Howdy Pardner\n")); +} +// Listing 1 + +#else +#include <stdio.h> + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + puts ("This example only works on g++ 2.96 and later.\n"); + return 0; +} + +#endif /* __GNUC__ */ diff --git a/ACE/examples/APG/Logging/Wrap_Macros_Alt.cpp b/ACE/examples/APG/Logging/Wrap_Macros_Alt.cpp new file mode 100644 index 00000000000..306eefcd83a --- /dev/null +++ b/ACE/examples/APG/Logging/Wrap_Macros_Alt.cpp @@ -0,0 +1,18 @@ +// $Id$ + +#include "Log_Msg_Alt.h" + +void foo (void); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("main"); + + // Listing 1 code/ch03 + ACE_DEBUG ((MY_DEBUG ACE_TEXT ("Hi Mom\n"))); + + ACE_DEBUG ((MY_DEBUG ACE_TEXT ("Goodnight\n"))); + // Listing 1 + + return 0; +} diff --git a/ACE/examples/APG/Logging/client.conf b/ACE/examples/APG/Logging/client.conf new file mode 100644 index 00000000000..1007e3aa7f6 --- /dev/null +++ b/ACE/examples/APG/Logging/client.conf @@ -0,0 +1 @@ +dynamic Client_Logging_Service Service_Object * netsvcs:_make_ACE_Client_Logging_Acceptor() active "-p 20009 -h localhost" diff --git a/ACE/examples/APG/Logging/logging.mpc b/ACE/examples/APG/Logging/logging.mpc new file mode 100644 index 00000000000..d40c2ae2704 --- /dev/null +++ b/ACE/examples/APG/Logging/logging.mpc @@ -0,0 +1,128 @@ +// -*- MPC -*- +// $Id$ + +project(Simple1) : aceexe { + exename = Simple1 + Source_Files { + Simple1.cpp + } +} + +project(Simple2) : aceexe { + exename = Simple2 + Source_Files { + Simple2.cpp + } +} + +project(Change Mask) : aceexe { + exename = Change_Mask + Source_Files { + Change_Mask.cpp + } +} + +project(Change Instance Default) : aceexe { + exename = Change_Instance_Default + Source_Files { + Change_Instance_Default.cpp + } +} + +project(Wrap Macros) : aceexe { + exename = Wrap_Macros + Source_Files { + Wrap_Macros.cpp + } +} + +project(Wrap Macros Alt) : aceexe { + exename = Wrap_Macros_Alt + Source_Files { + Wrap_Macros_Alt.cpp + } +} + +project(Trace Return) : aceexe { + exename = Trace_Return + Source_Files { + Trace_Return.cpp + } +} + +project(Use Stderr) : aceexe { + exename = Use_Stderr + Source_Files { + Use_Stderr.cpp + } +} + +project(Howto Syslog) : aceexe { + exename = Howto_Syslog + Source_Files { + Howto_Syslog.cpp + } +} + +project(Use Syslog) : aceexe { + exename = Use_Syslog + Source_Files { + Use_Syslog.cpp + } +} + +project(Use Ostream) : aceexe { + exename = Use_Ostream + Source_Files { + Use_Ostream.cpp + } +} + +project(Use Multiple Sinks) : aceexe { + exename = Use_Multiple_Sinks + Source_Files { + Use_Multiple_Sinks.cpp + } +} + +project(Use Callback) : aceexe { + exename = Use_Callback + Source_Files { + Use_Callback.cpp + } +} + +project(Use Callback2) : aceexe { + exename = Use_Callback2 + Source_Files { + Use_Callback2.cpp + } +} + +project(Use Logger) : aceexe { + exename = Use_Logger + Source_Files { + Use_Logger.cpp + } +} + +project(Use Logging Server) : aceexe { + exename = Use_Logging_Server + Source_Files { + Use_Logging_Server.cpp + } +} + +project(Use LogManager) : aceexe { + exename = Use_LogManager + Source_Files { + Use_LogManager.cpp + } +} + +project(Use Logging Strategy) : aceexe { + exename = Use_Logging_Strategy + Source_Files { + Use_Logging_Strategy.cpp + } +} diff --git a/ACE/examples/APG/Logging/logging_strategy.conf b/ACE/examples/APG/Logging/logging_strategy.conf new file mode 100644 index 00000000000..b63501ee185 --- /dev/null +++ b/ACE/examples/APG/Logging/logging_strategy.conf @@ -0,0 +1 @@ +dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-s log.out -f STDERR|OSTREAM -p INFO" diff --git a/ACE/examples/APG/Logging/server.conf b/ACE/examples/APG/Logging/server.conf new file mode 100644 index 00000000000..31f8fd95d9d --- /dev/null +++ b/ACE/examples/APG/Logging/server.conf @@ -0,0 +1,3 @@ +dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-s foobar -f STDERR|OSTREAM|VERBOSE" + +dynamic Server_Logging_Service Service_Object * netsvcs:_make_ACE_Server_Logging_Acceptor() active "-p 20009" diff --git a/ACE/examples/APG/Makefile.am b/ACE/examples/APG/Makefile.am new file mode 100644 index 00000000000..f79765c9348 --- /dev/null +++ b/ACE/examples/APG/Makefile.am @@ -0,0 +1,31 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +SUBDIRS = \ + Active_Objects \ + Config \ + Containers \ + Logging \ + Misc_IPC \ + Naming \ + Proactor \ + Processes \ + Reactor \ + Shared_Memory \ + Signals \ + Sockets \ + Streams \ + Svc_Config \ + ThreadManagement \ + ThreadPools \ + ThreadSafety \ + Threads \ + Timers + diff --git a/ACE/examples/APG/Misc_IPC/.cvsignore b/ACE/examples/APG/Misc_IPC/.cvsignore new file mode 100644 index 00000000000..155f8a18824 --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/.cvsignore @@ -0,0 +1,6 @@ +UDP_Broadcast +UDP_Broadcast +UDP_Multicast +UDP_Multicast +UDP_Unicast +UDP_Unicast diff --git a/ACE/examples/APG/Misc_IPC/Makefile.am b/ACE/examples/APG/Misc_IPC/Makefile.am new file mode 100644 index 00000000000..656f63fb00c --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/Makefile.am @@ -0,0 +1,69 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.UDP_Broadcast.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += UDP_Broadcast + +UDP_Broadcast_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +UDP_Broadcast_SOURCES = \ + UDP_Broadcast.cpp + +UDP_Broadcast_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.UDP_Multicast.am +noinst_PROGRAMS += UDP_Multicast + +UDP_Multicast_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +UDP_Multicast_SOURCES = \ + UDP_Multicast.cpp + +UDP_Multicast_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.UDP_Unicast.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += UDP_Unicast + +UDP_Unicast_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +UDP_Unicast_SOURCES = \ + UDP_Unicast.cpp + +UDP_Unicast_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Misc_IPC/UDP_Broadcast.cpp b/ACE/examples/APG/Misc_IPC/UDP_Broadcast.cpp new file mode 100644 index 00000000000..318be67b19c --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/UDP_Broadcast.cpp @@ -0,0 +1,34 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +// Listing 1 code/ch09 +#include "ace/OS_NS_string.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Bcast.h" + +int send_broadcast (u_short to_port) +{ + const char *message = "this is the message!\n"; + ACE_INET_Addr my_addr (static_cast<u_short> (10101)); + ACE_SOCK_Dgram_Bcast udp (my_addr); + ssize_t sent = udp.send (message, + ACE_OS::strlen (message) + 1, + to_port); + udp.close (); + if (sent == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("send")), -1); + return 0; +} +// Listing 1 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + send_broadcast (10); + return 0; +} diff --git a/ACE/examples/APG/Misc_IPC/UDP_Multicast.cpp b/ACE/examples/APG/Misc_IPC/UDP_Multicast.cpp new file mode 100644 index 00000000000..feb2baafc57 --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/UDP_Multicast.cpp @@ -0,0 +1,37 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +// Listing 1 code/ch09 +#include "ace/OS_NS_string.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Mcast.h" + +int send_multicast (const ACE_INET_Addr &mcast_addr) +{ + const char *message = "this is the message!\n"; + ACE_SOCK_Dgram_Mcast udp; + if (-1 == udp.join (mcast_addr)) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("join")), -1); + + ssize_t sent = udp.send (message, + ACE_OS::strlen (message) + 1); + udp.close (); + if (sent == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("send")), -1); + return 0; +} +// Listing 1 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_INET_Addr nop; + send_multicast (nop); + return 0; +} diff --git a/ACE/examples/APG/Misc_IPC/UDP_Unicast.cpp b/ACE/examples/APG/Misc_IPC/UDP_Unicast.cpp new file mode 100644 index 00000000000..ac3d4d00488 --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/UDP_Unicast.cpp @@ -0,0 +1,71 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +// Listing 1 code/ch09 +#include "ace/OS_NS_string.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram.h" + +int send_unicast (const ACE_INET_Addr &to) +{ + const char *message = "this is the message!\n"; + ACE_INET_Addr my_addr (static_cast<u_short> (10101)); + ACE_SOCK_Dgram udp (my_addr); + ssize_t sent = udp.send (message, + ACE_OS::strlen (message) + 1, + to); + udp.close (); + if (sent == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("send")), -1); + return 0; +} +// Listing 1 + +// Listing 2 code/ch09 +void echo_dgram (void) +{ + ACE_INET_Addr my_addr (static_cast<u_short> (10102)); + ACE_INET_Addr your_addr; + ACE_SOCK_Dgram udp (my_addr); + char buff[BUFSIZ]; + size_t buflen = sizeof (buff); + ssize_t recv_cnt = udp.recv (buff, buflen, your_addr); + if (recv_cnt > 0) + udp.send (buff, static_cast<size_t> (buflen), your_addr); + udp.close (); + return; +} +// Listing 2 + +// Listing 3 code/ch09 +#include "ace/SOCK_CODgram.h" +// Exclude 3 +static void show_codgram (void) +{ + char buff[BUFSIZ]; + size_t buflen = sizeof (buff); + // Exclude 3 + const ACE_TCHAR *peer = ACE_TEXT ("other_host:8042"); + ACE_INET_Addr peer_addr (peer); + ACE_SOCK_CODgram udp; + if (0 != udp.open (peer_addr)) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), peer)); + + // ... + + if (-1 == udp.send (buff, buflen)) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("send"))); + // Listing 3 +} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + show_codgram (); + return 0; +} diff --git a/ACE/examples/APG/Misc_IPC/misc_ipc.mpc b/ACE/examples/APG/Misc_IPC/misc_ipc.mpc new file mode 100644 index 00000000000..47e1c34758b --- /dev/null +++ b/ACE/examples/APG/Misc_IPC/misc_ipc.mpc @@ -0,0 +1,25 @@ +// -*- MPC -*- +// $Id$ + +project(UDP Broadcast) : aceexe { + avoids += ace_for_tao + exename = UDP_Broadcast + Source_Files { + UDP_Broadcast.cpp + } +} + +project(UDP Multicast) : aceexe { + exename = UDP_Multicast + Source_Files { + UDP_Multicast.cpp + } +} + +project(UDP Unicast) : aceexe { + avoids += ace_for_tao + exename = UDP_Unicast + Source_Files { + UDP_Unicast.cpp + } +} diff --git a/ACE/examples/APG/Naming/.cvsignore b/ACE/examples/APG/Naming/.cvsignore new file mode 100644 index 00000000000..e5fd579f85d --- /dev/null +++ b/ACE/examples/APG/Naming/.cvsignore @@ -0,0 +1,10 @@ +Netlocal +Netlocal +Netlocal_reader +Netlocal_reader +Nodelocal +Nodelocal +Nodelocal_shared +Nodelocal_shared +Nodelocal_shared_reader +Nodelocal_shared_reader diff --git a/ACE/examples/APG/Naming/EMail.h b/ACE/examples/APG/Naming/EMail.h new file mode 100644 index 00000000000..fc38913a10a --- /dev/null +++ b/ACE/examples/APG/Naming/EMail.h @@ -0,0 +1,28 @@ +// $Id$ + +#ifndef EMAIL_H +#define EMAIL_H + +#include "ace/Log_Msg.h" + +class EMail + { + public: + EMail() + { } + + int send (const char *to, + const char *from, + const char *subject, + const char *message) + { + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("To:\t%s\n"), to)); + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("From:\t%s\n"), from)); + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("Subject:\t%s\n"), subject)); + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\n%s\n"), message)); + + return 0; + } + }; + +#endif /* EMAIL_H */ diff --git a/ACE/examples/APG/Naming/Graph.cpp b/ACE/examples/APG/Naming/Graph.cpp new file mode 100644 index 00000000000..62ca52afd0d --- /dev/null +++ b/ACE/examples/APG/Naming/Graph.cpp @@ -0,0 +1,47 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "Graph.h" + +void Graph::graph (char *filename, Graphable_Element_List &data) +{ + data.sort (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Save graph to %C\n"), filename)); + + char h[10][10]; + for (int n = 0 ; n < 10 ; ++n ) + { + for (int j = 0; j < 10; ++j ) + { + h[n][j] = ' '; + } + } + + int l[10]; + int k = 0; + for (Graphable_Element_List::iterator i = data.begin (); + i != data.end (); + ++i, ++k ) + { + l[k] = (*i).when (); + + int temp = (int)((*i).temp () - 80.0); + + for (int j = 0; j <= temp; ++j) + { + h[k][j] = '#'; + } + } + + for (int m = 0 ; m < 10 ; ++m) + { + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%d "), l[m])); + + for (int j = 0; j < 10; ++j) + { + ACE_DEBUG ((LM_INFO, ACE_TEXT ("%c"), h[m][j])); + } + ACE_DEBUG ((LM_INFO, ACE_TEXT ("\n"))); + } +} diff --git a/ACE/examples/APG/Naming/Graph.h b/ACE/examples/APG/Naming/Graph.h new file mode 100644 index 00000000000..135b7d14f77 --- /dev/null +++ b/ACE/examples/APG/Naming/Graph.h @@ -0,0 +1,18 @@ +// $Id$ + +#ifndef GRAPH_H +#define GRAPH_H + +#include "Graphable_Element.h" + +class Graph + { + public: + Graph() + { + } + + void graph( char * filename, Graphable_Element_List & data ); + }; + +#endif /* GRAPH_H */ diff --git a/ACE/examples/APG/Naming/Graphable_Element.cpp b/ACE/examples/APG/Naming/Graphable_Element.cpp new file mode 100644 index 00000000000..c3ff6ee7b41 --- /dev/null +++ b/ACE/examples/APG/Naming/Graphable_Element.cpp @@ -0,0 +1,4 @@ +// $Id$ + +#include "Graphable_Element.h" + diff --git a/ACE/examples/APG/Naming/Graphable_Element.h b/ACE/examples/APG/Naming/Graphable_Element.h new file mode 100644 index 00000000000..42758934993 --- /dev/null +++ b/ACE/examples/APG/Naming/Graphable_Element.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef GRAPHABLE_ELEMENT_H +#define GRAPHABLE_ELEMENT_H + +#include "Name_Binding.h" +#include <list> + +// A helper class that knows how to sort two ACE_Name_Binding objects +// which contain temperature metrics. The value stored in the binding +// is expected to be of the format "time|temp". +// +// Listing 1 code/ch21 +class Graphable_Element : public Name_Binding +{ +public: + Graphable_Element (ACE_Name_Binding *entry) + : Name_Binding(entry) + { + sscanf (this->value (), "%d|%f", &this->when_, &this->temp_); + } + // Listing 1 + + // Listing 2 code/ch21 + inline int when (void) const + { + return this->when_; + } + + inline float temp (void) + { + return this->temp_; + } + // Listing 2 + + // Listing 3 code/ch21 + inline bool operator< (const Graphable_Element &other) const + { + return this->when () < other.when (); + } + // Listing 3 + + // Listing 4 code/ch21 +private: + int when_; + float temp_; +}; + +typedef std::list<Graphable_Element> Graphable_Element_List; +// Listing 4 + +#endif /* GRAPHABLE_ELEMENT_H */ diff --git a/ACE/examples/APG/Naming/Makefile.am b/ACE/examples/APG/Naming/Makefile.am new file mode 100644 index 00000000000..f73b1258348 --- /dev/null +++ b/ACE/examples/APG/Naming/Makefile.am @@ -0,0 +1,123 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Netlocal.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Netlocal + +Netlocal_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Netlocal_SOURCES = \ + Netlocal.cpp \ + Temperature_Monitor2.cpp \ + Temperature_Monitor2.h + +Netlocal_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Netlocal_Reader.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Netlocal_reader + +Netlocal_reader_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Netlocal_reader_SOURCES = \ + Graph.cpp \ + Netlocal_reader.cpp \ + Temperature_Grapher.cpp \ + Graph.h \ + Temperature_Grapher.h + +Netlocal_reader_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Nodelocal.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Nodelocal + +Nodelocal_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Nodelocal_SOURCES = \ + Nodelocal.cpp \ + Temperature_Monitor.cpp \ + Temperature_Monitor.h + +Nodelocal_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Nodelocal_Shared.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Nodelocal_shared + +Nodelocal_shared_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Nodelocal_shared_SOURCES = \ + Nodelocal_shared.cpp \ + Temperature_Monitor2.cpp \ + Temperature_Monitor2.h + +Nodelocal_shared_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Nodelocal_Shared_Reader.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Nodelocal_shared_reader + +Nodelocal_shared_reader_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Nodelocal_shared_reader_SOURCES = \ + Graph.cpp \ + Nodelocal_shared_reader.cpp \ + Temperature_Grapher.cpp \ + Temperature_Monitor.cpp \ + Graph.h \ + Temperature_Grapher.h \ + Temperature_Monitor.h + +Nodelocal_shared_reader_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Naming/Name_Binding.h b/ACE/examples/APG/Naming/Name_Binding.h new file mode 100644 index 00000000000..6c093a941f2 --- /dev/null +++ b/ACE/examples/APG/Naming/Name_Binding.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef NAME_BINDING_H +#define NAME_BINDING_H + +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/Auto_Ptr.h" +#include "ace/Name_Space.h" + +// Listing 1 code/ch21 +class Name_Binding +{ +public: + Name_Binding (ACE_Name_Binding *entry) + { + this->name_ = entry->name_.char_rep (); + this->value_ = entry->value_.char_rep (); + this->type_ = ACE_OS::strdup (entry->type_); + } + + Name_Binding (const ACE_NS_WString &n, + const ACE_NS_WString &v, + const char *t) + { + this->name_ = n.char_rep (); + this->value_ = v.char_rep (); + this->type_ = ACE_OS::strdup (t); + } + + ~Name_Binding () + { + delete this->name_; + delete this->value_; + ACE_OS::free (const_cast<char*> (this->type_)); + this->type_ = 0; + } + + char *name (void) + { return this->name_; } + + char *value (void) + { return this->value_; } + + const char *type (void) + { return this->type_; } + + int int_value (void) + { return ACE_OS::atoi (this->value ()); } + +private: + char *name_; + char *value_; + char *type_; +}; + +typedef auto_ptr<Name_Binding> Name_Binding_Ptr; +// Listing 1 + +#endif /* NAME_BINDING_H */ diff --git a/ACE/examples/APG/Naming/Naming_Context.h b/ACE/examples/APG/Naming/Naming_Context.h new file mode 100644 index 00000000000..abcf793b2b6 --- /dev/null +++ b/ACE/examples/APG/Naming/Naming_Context.h @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef NAMING_CONTEXT_H +#define NAMING_CONTEXT_H + +#include "ace/Naming_Context.h" +#include "ace/OS_NS_stdio.h" +#include "Name_Binding.h" + +// Listing 1 code/ch21 +class Naming_Context : public ACE_Naming_Context +{ +public: + typedef ACE_Naming_Context inherited; + + int rebind (const char *name_in, + const char *value_in, + const char *type_in = "") + { + return this->inherited::rebind (name_in, value_in, type_in); + } + + int rebind (const char *name_in, + float value_in, + const char *type_in = "") + { + char buf[BUFSIZ]; + ACE_OS::sprintf (buf, "%2f", value_in); + return this->inherited::rebind (name_in, + (const char *)buf, + type_in); + } + + int rebind (const char *name_in, + int value_in, + const char *type_in = "") + { + char buf[BUFSIZ]; + ACE_OS::sprintf (buf, "%d", value_in ); + return this->inherited::rebind (name_in, + (const char *)buf, + type_in); + } + // Listing 1 + + // Listing 2 code/ch21 + Name_Binding *fetch (const char *name) + { + ACE_NS_WString value; + char *type; + + if (this->resolve (name, value, type) != 0 || + value.length () < 1) + { + return 0; + } + + Name_Binding *rval = + new Name_Binding (ACE_NS_WString (name), + value, + type); + return rval; + } +// Listing 2 +}; + +#endif /* NAMING_CONTEXT_H */ diff --git a/ACE/examples/APG/Naming/Netlocal.cpp b/ACE/examples/APG/Naming/Netlocal.cpp new file mode 100644 index 00000000000..f1799ab3882 --- /dev/null +++ b/ACE/examples/APG/Naming/Netlocal.cpp @@ -0,0 +1,40 @@ +// $Id$ + +#include "Naming_Context.h" +#include "Temperature_Monitor2.h" +#include "Temperature_Monitor_Options.h" + +// Listing 1 code/ch21 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Temperature_Monitor_Options opt (argc, argv); + + Naming_Context process_context; + { + ACE_Name_Options *name_options = + process_context.name_options (); + name_options->context (ACE_Naming_Context::PROC_LOCAL); + ACE_TCHAR *nargv[] = { argv[0] }; + name_options->parse_args (sizeof(nargv) / sizeof(ACE_TCHAR*), + nargv); + process_context.open (name_options->context ()); + } + + Naming_Context shared_context; + { + ACE_Name_Options *name_options = + shared_context.name_options (); + name_options->process_name (argv[0]); + name_options->context (ACE_Naming_Context::NET_LOCAL); + shared_context.open (name_options->context ()); + } + + Temperature_Monitor2 temperature_monitor (opt, + process_context, + shared_context); + temperature_monitor.monitor (); + process_context.close (); + shared_context.close (); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Naming/Netlocal_reader.cpp b/ACE/examples/APG/Naming/Netlocal_reader.cpp new file mode 100644 index 00000000000..f77724aabbe --- /dev/null +++ b/ACE/examples/APG/Naming/Netlocal_reader.cpp @@ -0,0 +1,23 @@ +// $Id$ + +#include "Naming_Context.h" +#include "Temperature_Grapher.h" +#include "Temperature_Grapher_Options.h" + +// Listing 1 code/ch21 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Temperature_Grapher_Options opt (argc, argv); + + Naming_Context naming_context; + ACE_Name_Options *name_options = naming_context.name_options (); + name_options->process_name (argv[0]); + name_options->context (ACE_Naming_Context::NET_LOCAL); + naming_context.open (name_options->context ()); + + Temperature_Grapher grapher (opt, naming_context); + grapher.monitor (); + naming_context.close (); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Naming/Nodelocal.cpp b/ACE/examples/APG/Naming/Nodelocal.cpp new file mode 100644 index 00000000000..ca37a27e374 --- /dev/null +++ b/ACE/examples/APG/Naming/Nodelocal.cpp @@ -0,0 +1,37 @@ +// $Id$ + +#include "Naming_Context.h" +#include "Temperature_Monitor.h" +#include "Temperature_Monitor_Options.h" + +// Listing 1 code/ch21 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Temperature_Monitor_Options opt (argc, argv); + // Listing 1 + + // Listing 2 code/ch21 + Naming_Context naming_context; + + ACE_Name_Options *name_options = naming_context.name_options(); + // Listing 2 + + // Listing 3 code/ch21 + ACE_TCHAR *naming_options_argv[] = { argv[0] }; + name_options->parse_args + (sizeof(naming_options_argv) / sizeof(ACE_TCHAR*), + naming_options_argv); + name_options->context (ACE_Naming_Context::PROC_LOCAL); + naming_context.open (name_options->context ()); + // Listing 3 + + // Listing 4 code/ch21 + Temperature_Monitor temperature_monitor (opt, naming_context); + temperature_monitor.monitor (); + // Listing 4 + + // Listing 5 code/ch21 + naming_context.close (); + return 0; + // Listing 5 +} diff --git a/ACE/examples/APG/Naming/Nodelocal_shared.cpp b/ACE/examples/APG/Naming/Nodelocal_shared.cpp new file mode 100644 index 00000000000..34ea87aab2d --- /dev/null +++ b/ACE/examples/APG/Naming/Nodelocal_shared.cpp @@ -0,0 +1,43 @@ +// $Id$ + +#include "Naming_Context.h" +#include "Temperature_Monitor2.h" +#include "Temperature_Monitor_Options.h" + +// Listing 1 code/ch21 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Temperature_Monitor_Options opt (argc, argv); + Naming_Context process_context; + { + ACE_Name_Options *name_options = + process_context.name_options (); + name_options->context (ACE_Naming_Context::PROC_LOCAL); + ACE_TCHAR *nargv[] = { argv[0] }; + name_options->parse_args (sizeof(nargv) / sizeof(ACE_TCHAR*) , + nargv); + process_context.open (name_options->context ()); + } + + Naming_Context shared_context; + { + ACE_Name_Options *name_options = + shared_context.name_options (); + name_options->process_name (argv[0]); + name_options->context (ACE_Naming_Context::NODE_LOCAL); + shared_context.open (name_options->context ()); + } + + Temperature_Monitor2 temperature_monitor (opt, + process_context, + shared_context); + temperature_monitor.monitor (); + + process_context.close (); + shared_context.close (); + + return 0; +} +// Listing 1 + + diff --git a/ACE/examples/APG/Naming/Nodelocal_shared_reader.cpp b/ACE/examples/APG/Naming/Nodelocal_shared_reader.cpp new file mode 100644 index 00000000000..7385f09a496 --- /dev/null +++ b/ACE/examples/APG/Naming/Nodelocal_shared_reader.cpp @@ -0,0 +1,23 @@ +// $Id$ + +#include "Naming_Context.h" +#include "Temperature_Grapher.h" +#include "Temperature_Grapher_Options.h" + +// Listing 1 code/ch21 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Temperature_Grapher_Options opt (argc, argv); + + Naming_Context naming_context; + ACE_Name_Options *name_options = naming_context.name_options (); + name_options->process_name (argv[0]); + name_options->context (ACE_Naming_Context::NODE_LOCAL); + naming_context.open (name_options->context ()); + + Temperature_Grapher grapher (opt, naming_context); + grapher.monitor (); + naming_context.close (); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Naming/Temperature_Grapher.cpp b/ACE/examples/APG/Naming/Temperature_Grapher.cpp new file mode 100644 index 00000000000..e11367af4a0 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Grapher.cpp @@ -0,0 +1,81 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" + +#include "Graph.h" +#include "Graphable_Element.h" +#include "Temperature_Grapher.h" + +// Listing 1 code/ch21 +void Temperature_Grapher::monitor (void) +{ + for (;;) + { + this->update_graph (); + ACE_OS::sleep (this->opt_.poll_interval ()); + } +} +// Listing 1 + +// Listing 2 code/ch21 +void Temperature_Grapher::update_graph (void) +{ + Name_Binding_Ptr lastUpdate + (this->naming_context_.fetch ("lastUpdate")); + + if (!lastUpdate.get ()) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("No data to graph\n"))); + return; + } + // Listing 2 + + // Listing 3 code/ch21 + Name_Binding_Ptr lastGraphed + (this->naming_context_.fetch ("lastGraphed")); + + if (lastGraphed.get () && + lastGraphed->int_value () == lastUpdate->int_value ()) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Data already graphed\n"))); + return; + } + // Listing 3 + + // Listing 4 code/ch21 + ACE_BINDING_SET set; + if (this->naming_context_.list_name_entries + (set, "history[") != 0) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("There's nothing to graph\n"))); + return; + } + // Listing 4 + + // Listing 5 code/ch21 + Graphable_Element_List graphable; + ACE_BINDING_ITERATOR set_iterator (set); + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) != 0; + set_iterator.advance ()) + { + Name_Binding binding (entry); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s\t%s\t%s\n"), + binding.type (), + binding.name (), + binding.value ())); + + Graphable_Element *ge = new Graphable_Element (entry); + graphable.push_back (*ge); + } + // Listing 5 + + // Listing 6 code/ch21 + Graph g; + g.graph (lastUpdate->value (), graphable); + this->naming_context_.rebind ("lastGraphed", + lastUpdate->int_value ()); + // Listing 6 +} diff --git a/ACE/examples/APG/Naming/Temperature_Grapher.h b/ACE/examples/APG/Naming/Temperature_Grapher.h new file mode 100644 index 00000000000..610dac6a578 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Grapher.h @@ -0,0 +1,30 @@ +// $Id$ + +#ifndef TEMPERATURE_GRAPHER_H +#define TEMPERATURE_GRAPHER_H + +#include "Thermometer.h" +#include "Temperature_Grapher_Options.h" +#include "Naming_Context.h" + +class Temperature_Grapher + { + public: + Temperature_Grapher( Temperature_Grapher_Options & opt, + Naming_Context & naming_context ) + : opt_(opt), naming_context_(naming_context) + { + } + + void monitor(); + + protected: + void update_graph(); + + private: + Thermometer * thermometer_; + Temperature_Grapher_Options & opt_; + Naming_Context & naming_context_; + }; + +#endif /* TEMPERATURE_GRAPHER_H */ diff --git a/ACE/examples/APG/Naming/Temperature_Grapher_Options.h b/ACE/examples/APG/Naming/Temperature_Grapher_Options.h new file mode 100644 index 00000000000..e7a2dbe7c94 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Grapher_Options.h @@ -0,0 +1,21 @@ +// $Id$ + +#ifndef TEMPERATURE_GRAPHER_OPTIONS_H +#define TEMPERATURE_GRAPHER_OPTIONS_H + +class Temperature_Grapher_Options + { + public: + Temperature_Grapher_Options( int argc, ACE_TCHAR ** argv ) + { + ACE_UNUSED_ARG(argc); + ACE_UNUSED_ARG(argv); + } + + int poll_interval() + { + return 20; // every 20 seconds + } + }; + +#endif /* TEMPERATURE_GRAPHER_OPTIONS_H */ diff --git a/ACE/examples/APG/Naming/Temperature_Monitor.cpp b/ACE/examples/APG/Naming/Temperature_Monitor.cpp new file mode 100644 index 00000000000..8ac841b4108 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Monitor.cpp @@ -0,0 +1,133 @@ +// $Id$ + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" + +#include "Thermometer.h" +#include "Temperature_Monitor.h" +#include "EMail.h" + +// Listing 1 code/ch21 +Temperature_Monitor::Temperature_Monitor + (Temperature_Monitor_Options &opt, + Naming_Context &naming_context) + : opt_(opt), naming_context_(naming_context) +{ } +// Listing 1 + +// Listing 31 code/ch21 +void Temperature_Monitor::record_temperature (float temp) +{ + Name_Binding_Ptr current + (this->naming_context_.fetch ("current")); + if (current.get()) + { + this->naming_context_.rebind ("previous", + current->value ()); + } +// Listing 31 + +// Listing 32 code/ch21 + this->naming_context_.rebind ("current", temp); +// Listing 32 + +// Listing 33 code/ch21 + this->naming_context_.unbind ("lastReset"); + this->naming_context_.unbind ("resetCount"); +// Listing 33 +} + +// Listing 41 code/ch21 +void Temperature_Monitor::record_failure (void) +{ + Name_Binding_Ptr lastReset + (this->naming_context_.fetch ("lastReset")); + Name_Binding_Ptr resetCount + (this->naming_context_.fetch ("resetCount")); +// Listing 41 + +// Listing 42 code/ch21 + int now = ACE_OS::time (); + int lastResetTime; + if (lastReset.get ()) + { + lastResetTime = lastReset->int_value (); + } + else + { + this->naming_context_.rebind ("lastReset", now); + lastResetTime = now; + } + // Listing 42 + + // Listing 43 code/ch21 + if (now - lastResetTime > this->opt_.reset_interval ()) + { + this->reset_device (resetCount); + } + // Listing 43 +} + +// Listing 5 code/ch21 +void +Temperature_Monitor::reset_device (Name_Binding_Ptr &resetCount) +{ + int number_of_resets = 1; + if (resetCount.get ()) + { + number_of_resets = resetCount->int_value () + 1; + if (number_of_resets > this->opt_.excessive_resets ()) + { + // Exclude 5 + EMail notification; + + char message[BUFSIZ]; + ACE_OS::sprintf (message, + "Thermometer: %s\n" + "Reset Count: %d\n", + this->thermometer_->address(), + number_of_resets); + + notification.send (this->opt_.admin_email (), + this->opt_.email_from (), + "Excessive number of thermometer resets", + message); + // Exclude 5 + } + } + this->thermometer_->reset (); + this->naming_context_.rebind ("lastReset", + (int) ACE_OS::time ()); + this->naming_context_.rebind ("resetCount", + number_of_resets); +} +// Listing 5 + +// Listing 2 code/ch21 +void Temperature_Monitor::monitor (void) +{ + this->thermometer_ = + new Thermometer (this->opt_.thermometer_address ()); + + for(;;) + { + float temp = this->thermometer_->temperature (); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("Read temperature %.2f\n"), + temp)); + + if (temp >= 0) + { + this->record_temperature (temp); + } + else + { + this->record_failure (); + } + + ACE_OS::sleep (this->opt_.poll_interval ()); + } + + delete this->thermometer_; +} +// Listing 2 diff --git a/ACE/examples/APG/Naming/Temperature_Monitor.h b/ACE/examples/APG/Naming/Temperature_Monitor.h new file mode 100644 index 00000000000..3b85b100fa1 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Monitor.h @@ -0,0 +1,29 @@ +// $Id$ + +#ifndef TEMPERATURE_MONITOR_H +#define TEMPERATURE_MONITOR_H + +#include "Thermometer.h" +#include "Temperature_Monitor_Options.h" +#include "Naming_Context.h" + +class Temperature_Monitor + { + public: + Temperature_Monitor( Temperature_Monitor_Options & opt, + Naming_Context & naming_context ); + + void monitor(); + + protected: + void record_temperature(float temp); + void record_failure(); + void reset_device(Name_Binding_Ptr & resetCount); + + private: + Thermometer * thermometer_; + Temperature_Monitor_Options & opt_; + Naming_Context & naming_context_; + }; + +#endif /* TEMPERATURE_MONITOR_H */ diff --git a/ACE/examples/APG/Naming/Temperature_Monitor2.cpp b/ACE/examples/APG/Naming/Temperature_Monitor2.cpp new file mode 100644 index 00000000000..b24f1c1f329 --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Monitor2.cpp @@ -0,0 +1,145 @@ +// $Id$ + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" + +#include "Thermometer.h" +#include "Temperature_Monitor2.h" +#include "EMail.h" + +// Listing 1 code/ch21 +void Temperature_Monitor2::record_temperature (float temp) +{ + Name_Binding_Ptr current + (this->naming_context_.fetch ("current")); + if (current.get ()) + { + this->naming_context_.rebind ("previous", + current->value ()); + } + + this->record_history (temp); + + this->naming_context_.unbind ("lastFailure"); + this->naming_context_.unbind ("lastReset"); + this->naming_context_.unbind ("resetCount"); +} +// Listing 1 + +// Listing 2 code/ch21 +void Temperature_Monitor2::record_history (float temp) +{ + int now = (int)ACE_OS::time (); + this->shared_context_.rebind ("lastUpdate", now); + + Name_Binding_Ptr counter + (this->shared_context_.fetch ("counter")); + int counterValue = counter.get () ? counter->int_value () : 0; + + char name[BUFSIZ]; + ACE_OS::sprintf (name, "history[%d]", counterValue); + + char value[BUFSIZ]; + ACE_OS::sprintf (value, "%d|%.2f", now, temp); + + this->shared_context_.rebind (name, value); + + ++counterValue; + counterValue %= this->opt_.history_size (); + this->shared_context_.rebind ("counter", counterValue); +} +// Listing 2 + +void Temperature_Monitor2::reset_device (Name_Binding_Ptr &resetCount) +{ + int number_of_resets = 1; + + if (resetCount.get ()) + { + number_of_resets = resetCount->int_value () + 1; + + if (number_of_resets > this->opt_.excessive_resets ()) + { + EMail notification; + + char message[BUFSIZ]; + ACE_OS::sprintf (message, + "Thermometer: %s\n" + "Reset Count: %d\n", + this->thermometer_->address (), + number_of_resets); + + notification.send (this->opt_.admin_email (), + this->opt_.email_from (), + "Excessive number of thermometer resets", + message); + } + } + + this->thermometer_->reset (); + + this->naming_context_.rebind ("lastReset", (int)ACE_OS::time ()); + this->naming_context_.rebind ("resetCount", number_of_resets); +} + +void Temperature_Monitor2::record_failure (void) +{ + Name_Binding_Ptr lastFailure (this->naming_context_.fetch ("lastFailure")); + Name_Binding_Ptr lastReset (this->naming_context_.fetch ("lastReset")); + Name_Binding_Ptr resetCount (this->naming_context_.fetch ("resetCount")); + + int now = ACE_OS::time (); + + int lastFailureTime; + int lastResetTime = 0; + + if (lastFailure.get ()) + { + lastFailureTime = lastFailure->int_value (); + } + else + { + this->naming_context_.rebind ("firstFailure", now); + this->naming_context_.rebind ("lastReset", now); + lastFailureTime = now; + lastResetTime = now; + } + + if (lastReset.get ()) + { + lastResetTime = lastReset->int_value (); + } + + if (now - lastResetTime > this->opt_.reset_interval ()) + { + this->reset_device (resetCount); + } + + this->naming_context_.rebind ("lastFailure", now); +} + +void Temperature_Monitor2::monitor (void) +{ + this->thermometer_ = new Thermometer (this->opt_.thermometer_address ()); + + for (;;) + { + float temp = this->thermometer_->temperature (); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("Read temperature %.2f\n"), temp)); + + if (temp >= 0) + { + this->record_temperature (temp); + } + else + { + this->record_failure (); + } + + ACE_OS::sleep (this->opt_.poll_interval ()); + } + + delete this->thermometer_; +} diff --git a/ACE/examples/APG/Naming/Temperature_Monitor2.h b/ACE/examples/APG/Naming/Temperature_Monitor2.h new file mode 100644 index 00000000000..b887e5c8e4c --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Monitor2.h @@ -0,0 +1,36 @@ +// $Id$ + +#ifndef TEMPERATURE_MONITOR_H +#define TEMPERATURE_MONITOR_H + +#include "Thermometer.h" +#include "Temperature_Monitor_Options.h" +#include "Naming_Context.h" + +class Temperature_Monitor2 +{ +public: + Temperature_Monitor2 (Temperature_Monitor_Options & opt, + Naming_Context & naming_context, + Naming_Context & shared_context) + : opt_(opt), + naming_context_(naming_context), + shared_context_(shared_context) + { } + + void monitor (void); + +protected: + void record_temperature (float temp); + void record_history (float temp); + void record_failure (void); + void reset_device (Name_Binding_Ptr & resetCount); + +private: + Thermometer *thermometer_; + Temperature_Monitor_Options &opt_; + Naming_Context &naming_context_; + Naming_Context &shared_context_; +}; + +#endif /* TEMPERATURE_MONITOR_H */ diff --git a/ACE/examples/APG/Naming/Temperature_Monitor_Options.h b/ACE/examples/APG/Naming/Temperature_Monitor_Options.h new file mode 100644 index 00000000000..95fb82faa9b --- /dev/null +++ b/ACE/examples/APG/Naming/Temperature_Monitor_Options.h @@ -0,0 +1,48 @@ +// $Id$ + +#ifndef TEMPERATURE_MONITOR_OPTIONS_H +#define TEMPERATURE_MONITOR_OPTIONS_H + +class Temperature_Monitor_Options + { + public: + Temperature_Monitor_Options (int, ACE_TCHAR *[]) + { } + + const char *thermometer_address (void) + { + return "serial:// s0/0x3e52"; + } + + int poll_interval (void) + { + return 10; // every 10 seconds + } + + int reset_interval (void) + { + return 60; // sixty seconds + } + + int excessive_resets (void) + { + return 5; // no response in 5 minutes + } + + const char *admin_email (void) + { + return "root@localhost"; + } + + const char *email_from (void) + { + return "temperature monitor"; + } + + int history_size() + { + return 10; + } + }; + +#endif /* TEMPERATURE_MONITOR_OPTIONS_H */ diff --git a/ACE/examples/APG/Naming/Thermometer.h b/ACE/examples/APG/Naming/Thermometer.h new file mode 100644 index 00000000000..cfdf1ca0f3d --- /dev/null +++ b/ACE/examples/APG/Naming/Thermometer.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef THERMOMETER_H +#define THERMOMETER_H + +#include "ace/OS_NS_stdlib.h" +#include "ace/Log_Msg.h" + +class Thermometer +{ +public: + Thermometer (const char *addr) + : addr_(addr), threshold_(5) + { } + + float temperature (void) + { + int success = ACE_OS::rand () % 10; + if (success < this->threshold_) + { + this->threshold_ = 7; + return -1.0; + } + + this->threshold_ = 3; + int itemp = 80 + ACE_OS::rand () % 10; // 80 <= t <= 90 + return (float)itemp; + } + + const char *address (void) + { + return this->addr_; + } + + void reset (void) + { + this->threshold_ = 4; + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("Resetting thermometer %C\n"), + this->address ())); + } + +private: + const char *addr_; + int threshold_; +}; + +#endif /* THERMOMETER_H */ diff --git a/ACE/examples/APG/Naming/naming.mpc b/ACE/examples/APG/Naming/naming.mpc new file mode 100644 index 00000000000..fda823954fc --- /dev/null +++ b/ACE/examples/APG/Naming/naming.mpc @@ -0,0 +1,50 @@ +// -*- MPC -*- +// $Id$ + +project(Netlocal) : aceexe { + avoids += ace_for_tao + exename = Netlocal + Source_Files { + Netlocal.cpp + Temperature_Monitor2.cpp + } +} + +project(Netlocal Reader) : aceexe { + avoids += ace_for_tao + exename = Netlocal_reader + Source_Files { + Netlocal_reader.cpp + Graph.cpp + Temperature_Grapher.cpp + } +} + +project(Nodelocal) : aceexe { + avoids += ace_for_tao + exename = Nodelocal + Source_Files { + Nodelocal.cpp + Temperature_Monitor.cpp + } +} + +project(Nodelocal Shared) : aceexe { + avoids += ace_for_tao + exename = Nodelocal_shared + Source_Files { + Nodelocal_shared.cpp + Temperature_Monitor2.cpp + } +} + +project(Nodelocal Shared Reader) : aceexe { + avoids += ace_for_tao + exename = Nodelocal_shared_reader + Source_Files { + Nodelocal_shared_reader.cpp + Graph.cpp + Temperature_Grapher.cpp + Temperature_Monitor.cpp + } +} diff --git a/ACE/examples/APG/Naming/svc.conf b/ACE/examples/APG/Naming/svc.conf new file mode 100644 index 00000000000..550ef992177 --- /dev/null +++ b/ACE/examples/APG/Naming/svc.conf @@ -0,0 +1 @@ +dynamic Name_Server Service_Object * netsvcs:_make_ACE_Name_Acceptor() "-p 20012" diff --git a/ACE/examples/APG/Proactor/.cvsignore b/ACE/examples/APG/Proactor/.cvsignore new file mode 100644 index 00000000000..64b35fb3d57 --- /dev/null +++ b/ACE/examples/APG/Proactor/.cvsignore @@ -0,0 +1,2 @@ +HA_Proactive_Status +HA_Proactive_Status diff --git a/ACE/examples/APG/Proactor/HA_Proactive_Status.cpp b/ACE/examples/APG/Proactor/HA_Proactive_Status.cpp new file mode 100644 index 00000000000..9d9b9dfb0e5 --- /dev/null +++ b/ACE/examples/APG/Proactor/HA_Proactive_Status.cpp @@ -0,0 +1,163 @@ +/* +** $Id$ +** +** Example program from The ACE Programmer's Guide, Chapter 8. +** Copyright 2003 Addison-Wesley. All Rights Reserved. +*/ + +#include "HA_Proactive_Status.h" +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" +#include "ace/Proactor.h" +#include "ace/os_include/arpa/os_inet.h" + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + +// Listing 1 code/ch08 +void +HA_Proactive_Service::open (ACE_HANDLE h, ACE_Message_Block&) +{ + this->handle (h); + if (this->reader_.open (*this) != 0 || + this->writer_.open (*this) != 0 ) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("HA_Proactive_Service open"))); + delete this; + return; + } + + ACE_Message_Block *mb; + ACE_NEW_NORETURN (mb, ACE_Message_Block (1024)); + if (this->reader_.read (*mb, mb->space ()) != 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("HA_Proactive_Service begin read"))); + mb->release (); + delete this; + return; + } + + // mb is now controlled by Proactor framework. + return; +} +// Listing 1 + +// Listing 2 code/ch08 +void +HA_Proactive_Service::handle_read_stream + (const ACE_Asynch_Read_Stream::Result &result) +{ + ACE_Message_Block &mb = result.message_block (); + if (!result.success () || result.bytes_transferred () == 0) + { + mb.release (); + delete this; + } + else + { + if (this->writer_.write (mb, mb.length ()) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("starting write"))); + mb.release (); + } + else + { + ACE_Message_Block *new_mb; + ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024)); + this->reader_.read (*new_mb, new_mb->space ()); + } + } + return; +} +// Listing 2 + +// Listing 3 code/ch08 +void +HA_Proactive_Service::handle_write_stream +(const ACE_Asynch_Write_Stream::Result &result) +{ + result.message_block ().release (); + return; +} +// Listing 3 + +// The network address check only works for BSD-ish systems. This +// sort of network number accessor should be added to ACE_INET_Addr +// at some point... +#if defined (ACE_WIN32) +int +HA_Proactive_Acceptor::validate_connection +(const ACE_Asynch_Accept::Result&, + const ACE_INET_Addr&, + const ACE_INET_Addr&) +{ + return 0; +} +#else + +// Listing 4 code/ch08 +int +HA_Proactive_Acceptor::validate_connection ( + const ACE_Asynch_Accept::Result&, + const ACE_INET_Addr& remote, + const ACE_INET_Addr& local) +{ + struct in_addr *remote_addr = + reinterpret_cast<struct in_addr*> (remote.get_addr ()); + struct in_addr *local_addr = + reinterpret_cast<struct in_addr*> (local.get_addr ()); + if (inet_netof (*local_addr) == inet_netof (*remote_addr)) + return 0; + + return -1; +} +// Listing 4 + +#endif /* ACE_WIN32 */ + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 5 code/ch08 + ACE_INET_Addr listen_addr; // Set up with listen port + HA_Proactive_Acceptor aio_acceptor; + if (0 != aio_acceptor.open (listen_addr, + 0, // bytes_to_read + 0, // pass_addresses + ACE_DEFAULT_BACKLOG, + 1, // reuse_addr + 0, // proactor + 1)) // validate_new_connection + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("acceptor open")), 1); + // Listing 5 + +#if 0 + // Listing 6 code/ch08 + ACE_INET_Addr peer_addr; // Set up peer addr + ACE_Asynch_Connector<HA_Proactive_Service> aio_connect; + aio_connect.connect (peer_addr); + // Listing 6 +#endif + + // Listing 7 code/ch08 + ACE_Proactor::instance ()->proactor_run_event_loop (); + // Listing 7 + return 0; +} + +#else + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("This example requires asynchronous I/O support.\n"))); + return 1; +} + +#endif /* (ACE_WIN32 && != ACE_HAS_WINCE) || ACE_HAS_AIO_CALLS*/ + diff --git a/ACE/examples/APG/Proactor/HA_Proactive_Status.h b/ACE/examples/APG/Proactor/HA_Proactive_Status.h new file mode 100644 index 00000000000..f66080b62cd --- /dev/null +++ b/ACE/examples/APG/Proactor/HA_Proactive_Status.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +/* +** $Id$ +** +** Example program from The ACE Programmer's Guide, Chapter 8. +** Copyright 2003 Addison-Wesley. All Rights Reserved. +*/ + +#ifndef __HA_PROACTIVE_STATUS_H +#define __HA_PROACTIVE_STATUS_H + +#include "ace/OS_NS_sys_socket.h" +#include "ace/Asynch_IO.h" +#include "ace/Service_Object.h" +// Listing 1 code/ch08 +#include "ace/Asynch_IO.h" + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + +class HA_Proactive_Service : public ACE_Service_Handler +{ +public: + ~HA_Proactive_Service () + { + if (this->handle () != ACE_INVALID_HANDLE) + ACE_OS::closesocket (this->handle ()); + } + + virtual void open (ACE_HANDLE h, ACE_Message_Block&); + + // This method will be called when an asynchronous read + // completes on a stream. + virtual void handle_read_stream + (const ACE_Asynch_Read_Stream::Result &result); + + // This method will be called when an asynchronous write + // completes on a stream. + virtual void handle_write_stream + (const ACE_Asynch_Write_Stream::Result &result); + +private: + ACE_Asynch_Read_Stream reader_; + ACE_Asynch_Write_Stream writer_; +}; +// Listing 1 + +// Listing 2 code/ch08 +#include "ace/Asynch_Acceptor.h" +#include "ace/INET_Addr.h" + +class HA_Proactive_Acceptor : + public ACE_Asynch_Acceptor<HA_Proactive_Service> +{ +public: + virtual int validate_connection + (const ACE_Asynch_Accept::Result& result, + const ACE_INET_Addr &remote, + const ACE_INET_Addr &local); +}; +// Listing 2 + +#endif /* (ACE_WIN32 && != ACE_HAS_WINCE) || ACE_HAS_AIO_CALLS*/ + +#if 0 +// Listing 3 code/ch08 +template <class HANDLER> +class ACE_Asynch_Acceptor : public ACE_Handler + ... +protected: + virtual HANDLER *make_handler (void) + { + return new HANDLER; + } +// Listing 3 +#endif + +class HA_Proactive_Status : public ACE_Service_Object +{ +public: + // Initializes object when dynamic linking occurs. + virtual int init (int argc, ACE_TCHAR *argv[]); + + // Terminates object when dynamic unlinking occurs. + virtual int fini (void); +}; + +#endif /* __HA_PROACTIVE_STATUS_H */ diff --git a/ACE/examples/APG/Proactor/Makefile.am b/ACE/examples/APG/Proactor/Makefile.am new file mode 100644 index 00000000000..a7632af1d4f --- /dev/null +++ b/ACE/examples/APG/Proactor/Makefile.am @@ -0,0 +1,39 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.HA_Proactive_Status.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS = HA_Proactive_Status + +HA_Proactive_Status_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HA_Proactive_Status_SOURCES = \ + HA_Proactive_Status.cpp \ + HA_Proactive_Status.h + +HA_Proactive_Status_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Proactor/proactor.mpc b/ACE/examples/APG/Proactor/proactor.mpc new file mode 100644 index 00000000000..85ef950ae66 --- /dev/null +++ b/ACE/examples/APG/Proactor/proactor.mpc @@ -0,0 +1,10 @@ +// -*- MPC -*- +// $Id$ + +project(HA Proactive Status) : aceexe { + avoids += ace_for_tao + exename = HA_Proactive_Status + Source_Files { + HA_Proactive_Status.cpp + } +} diff --git a/ACE/examples/APG/Processes/.cvsignore b/ACE/examples/APG/Processes/.cvsignore new file mode 100644 index 00000000000..187cf413af2 --- /dev/null +++ b/ACE/examples/APG/Processes/.cvsignore @@ -0,0 +1,8 @@ +Process_Manager_Death +Process_Manager_Death +Process_Manager_Spawn +Process_Manager_Spawn +Process_Mutex +Process_Mutex +Spawn +Spawn diff --git a/ACE/examples/APG/Processes/Makefile.am b/ACE/examples/APG/Processes/Makefile.am new file mode 100644 index 00000000000..5c45a506304 --- /dev/null +++ b/ACE/examples/APG/Processes/Makefile.am @@ -0,0 +1,90 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Process_Manager_Death.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Manager_Death + +Process_Manager_Death_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Manager_Death_SOURCES = \ + Process_Manager_Death.cpp + +Process_Manager_Death_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Process_Manager_Spawn.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Manager_Spawn + +Process_Manager_Spawn_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Manager_Spawn_SOURCES = \ + Process_Manager_Spawn.cpp + +Process_Manager_Spawn_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Process_Mutex.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Mutex + +Process_Mutex_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Mutex_SOURCES = \ + Process_Mutex.cpp + +Process_Mutex_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Spawn.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Spawn + +Spawn_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Spawn_SOURCES = \ + Spawn.cpp + +Spawn_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Processes/Process_Manager_Death.cpp b/ACE/examples/APG/Processes/Process_Manager_Death.cpp new file mode 100644 index 00000000000..51a8d911458 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Manager_Death.cpp @@ -0,0 +1,67 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Process_Manager.h" +#include "ace/Reactor.h" + +static const int NCHILDREN = 2; + +// Listing 1 code/ch10 +class DeathHandler: public ACE_Event_Handler +{ +public: + DeathHandler () : count_(0) + { + ACE_TRACE (ACE_TEXT ("DeathHandler::DeathHandler")); + } + + virtual int handle_exit (ACE_Process * process) + { + ACE_TRACE (ACE_TEXT ("DeathHandler::handle_exit")); + + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Process %d exited with exit code %d\n"), + process->getpid (), process->return_value ())); + + if (++count_ == NCHILDREN) + ACE_Reactor::instance ()->end_reactor_event_loop (); + + return 0; + } + +private: + int count_; +}; +// Listing 1 +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Running as a child. + return 0; + + // Instantiate a process manager with space for + // 10 processes. + ACE_Process_Manager pm (10, ACE_Reactor::instance ()); + + // Create a process termination handler. + DeathHandler handler; + + // Specify the options for the new processes to be spawned. + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + + // Spawn two child processes. + pid_t pids[NCHILDREN]; + pm.spawn_n (NCHILDREN, options, pids); + + // Register handler to be called when these processes exit. + for (int i = 0; i < NCHILDREN; i++) + pm.register_handler (&handler, pids[i]); + + // Run the reactor event loop waiting for events to occur. + ACE_Reactor::instance ()->run_reactor_event_loop (); + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp b/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp new file mode 100644 index 00000000000..dd61ae9bae8 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp @@ -0,0 +1,59 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +// Listing 0 code/ch10 +#include "ace/Process_Manager.h" + +static const int NCHILDREN = 2; + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Running as a child. + { + ACE_OS::sleep (10); + } + else // Running as a parent. + { + // Get the processwide process manager. + ACE_Process_Manager* pm = ACE_Process_Manager::instance (); + + // Specify the options for the new processes + // to be spawned. + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + + // Spawn two child processes. + pid_t pids[NCHILDREN]; + pm->spawn_n (NCHILDREN, options, pids); + + // Destroy the first child. + pm->terminate (pids[0]); + + // Wait for the child we just terminated. + ACE_exitcode status; + pm->wait (pids[0], &status); + + // Get the results of the termination. + +#if !defined(ACE_WIN32) + if (WIFSIGNALED (status) != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%d died because of a signal ") + ACE_TEXT ("of type %d\n"), + pids[0], WTERMSIG (status))); +#else + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("The process terminated with exit code %d\n"), + status)); +#endif /*ACE_WIN32*/ + + // Wait for all (only one left) of the + // children to exit. + pm->wait (0); + } + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Process_Mutex.cpp b/ACE/examples/APG/Processes/Process_Mutex.cpp new file mode 100644 index 00000000000..2afb89803b9 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Mutex.cpp @@ -0,0 +1,79 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +#include "ace/Process.h" +#include "ace/Process_Mutex.h" + +// Listing 1 code/ch10 +class GResourceUser +{ +public: + GResourceUser (ACE_Process_Mutex &mutex) : gmutex_(mutex) + { + ACE_TRACE (ACE_TEXT ("GResourceUser::GResourceUser")); + } + + void run (void) + { + ACE_TRACE (ACE_TEXT ("GResourceUser::run")); + + int count = 0; + while (count++ < 10) + { + int result = this->gmutex_.acquire (); + ACE_ASSERT (result == 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P| %t) has the mutex\n"))); + + // Access Global resource + ACE_OS::sleep (1); + + result = this->gmutex_.release (); + ACE_ASSERT (result == 0); + ACE_OS::sleep (1); // Give other process a chance. + } + } + +private: + ACE_Process_Mutex &gmutex_; +}; +// Listing 1 + +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Run as the child. + { + // Create or get the global mutex. + ACE_Process_Mutex mutex ("GlobalMutex"); + + GResourceUser acquirer (mutex); + acquirer.run (); + } + else // Run as the parent. + { + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + ACE_Process processa, processb; + + pid_t pida = processa.spawn (options); + pid_t pidb = processb.spawn (options); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Spawned processes; pids %d:%d\n"), + pida, pidb)); + + if (processa.wait() == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("processa wait")), -1); + + if (processb.wait() == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("processb wait")), -1); + } + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Spawn.cpp b/ACE/examples/APG/Processes/Spawn.cpp new file mode 100644 index 00000000000..0776a44a8ec --- /dev/null +++ b/ACE/examples/APG/Processes/Spawn.cpp @@ -0,0 +1,206 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_pwd.h" +#include "ace/os_include/os_pwd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Process.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch10 +class Manager : public ACE_Process +{ +public: + Manager (const ACE_TCHAR* program_name) + { + ACE_TRACE ("Manager::Manager"); + ACE_OS::strcpy (programName_, program_name); + } + + int doWork (void) + { + ACE_TRACE ("Manager::doWork"); + + // Spawn the new process; prepare() hook is called first. + ACE_Process_Options options; + pid_t pid = this->spawn (options); + if (pid == ACE_INVALID_PID) + ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("spawn")), -1); + + // Wait forever for my child to exit. + if (this->wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("wait")), -1); + + // Dump whatever happened. + this->dumpRun (); + return 0; + } +// Listing 1 + +private: + // Listing 3 code/ch10 + int dumpRun (void) + { + ACE_TRACE ("Manager::dumpRun"); + + if (ACE_OS::lseek (this->outputfd_, 0, SEEK_SET) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("lseek")), -1); + + char buf[1024]; + ssize_t length = 0; + + // Read the contents of the error stream written + // by the child and print it out. + while ((length = ACE_OS::read (this->outputfd_, + buf, sizeof(buf)-1)) > 0) + { + buf[length] = 0; + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%C\n"), buf)); + } + + ACE_OS::close (this->outputfd_); + return 0; + } + // Listing 3 + + // Listing 2 code/ch10 + // prepare() is inherited from ACE_Process. + int prepare (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::prepare"); + + options.command_line (ACE_TEXT ("%s 1"), this->programName_); + if (this->setStdHandles (options) == -1 || + this->setEnvVariable (options) == -1) + return -1; +#if !defined (ACE_WIN32) && !defined (ACE_LACKS_PWD_FUNCTIONS) + return this->setUserID (options); +#else + return 0; +#endif + } + + int setStdHandles (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setStdHandles"); + + ACE_OS::unlink ("output.dat"); + this->outputfd_ = + ACE_OS::open ("output.dat", O_RDWR | O_CREAT); + return options.set_handles + (ACE_STDIN, ACE_STDOUT, this->outputfd_); + } + + int setEnvVariable (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setEnvVariables"); + return options.setenv + (ACE_TEXT ("PRIVATE_VAR=/that/seems/to/be/it")); + } + // Listing 2 + +#if !defined (ACE_LACKS_PWD_FUNCTIONS) + // Listing 10 code/ch10 + int setUserID (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setUserID"); + passwd* pw = ACE_OS::getpwnam ("nobody"); + if (pw == 0) + return -1; + options.seteuid (pw->pw_uid); + return 0; + } + // Listing 10 +#endif /* !ACE_LACKS_PWD_FUNCTIONS */ + +private: + ACE_HANDLE outputfd_; + ACE_TCHAR programName_[256]; +}; + +// Listing 4 code/ch10 +class Slave +{ +public: + Slave () + { + ACE_TRACE ("Slave::Slave"); + } + + int doWork (void) + { + ACE_TRACE ("Slave::doWork"); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) started at %T, parent is %d\n"), + ACE_OS::getppid ())); + this->showWho (); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) the private environment is %s\n"), + ACE_OS::getenv ("PRIVATE_VAR"))); + + ACE_TCHAR str[128]; + ACE_OS::sprintf (str, ACE_TEXT ("(%d) Enter your command\n"), + static_cast<int>(ACE_OS::getpid ())); + ACE_OS::write (ACE_STDOUT, str, ACE_OS::strlen (str)); + this->readLine (str); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Executed: %C\n"), + str)); + return 0; + } +// Listing 4 + + void showWho (void) + { + ACE_TRACE ("Slave::showWho"); +#if !defined (ACE_LACKS_PWD_FUNCTIONS) + passwd *pw = ::getpwuid (::geteuid ()); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) Running this process as:%s\n"), + pw->pw_name)); +#endif + } + + ACE_TCHAR* readLine (ACE_TCHAR* str) + { + ACE_TRACE ("Slave::readLine"); + + int i = 0; + while (true) + { + ssize_t retval = ACE_OS::read (ACE_STDIN, &str[i], 1); + if (retval > 0) + { + if (str[i] == '\n') + { + str[++i] = 0; + return str; + } + i++; + } + else + return str; + } + } +}; + +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Slave mode + { + Slave s; + return s.doWork (); + } + + // Else, Master mode + Manager m (argv[0]); + return m.doWork (); +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/processes.mpc b/ACE/examples/APG/Processes/processes.mpc new file mode 100644 index 00000000000..a7cb01040bb --- /dev/null +++ b/ACE/examples/APG/Processes/processes.mpc @@ -0,0 +1,34 @@ +// -*- MPC -*- +// $Id$ + +project(Process Manager Death) : aceexe { + avoids += ace_for_tao + exename = Process_Manager_Death + Source_Files { + Process_Manager_Death.cpp + } +} + +project(Process Manager Spawn) : aceexe { + avoids += ace_for_tao + exename = Process_Manager_Spawn + Source_Files { + Process_Manager_Spawn.cpp + } +} + +project(Process Mutex) : aceexe { + avoids += ace_for_tao + exename = Process_Mutex + Source_Files { + Process_Mutex.cpp + } +} + +project(Spawn) : aceexe { + avoids += ace_for_tao + exename = Spawn + Source_Files { + Spawn.cpp + } +} diff --git a/ACE/examples/APG/Reactor/.cvsignore b/ACE/examples/APG/Reactor/.cvsignore new file mode 100644 index 00000000000..c2d63b45dcf --- /dev/null +++ b/ACE/examples/APG/Reactor/.cvsignore @@ -0,0 +1,16 @@ +Client +Client +HAStatus +HAStatus +HAStatus-AC +HAStatus-AC +Reschedule +Reschedule +Schedule_Timers +Schedule_Timers +Timer_Cancel +Timer_Cancel +Timer_State_Data +Timer_State_Data +Timers +Timers diff --git a/ACE/examples/APG/Reactor/Client.cpp b/ACE/examples/APG/Reactor/Client.cpp new file mode 100644 index 00000000000..b2773bbf7f3 --- /dev/null +++ b/ACE/examples/APG/Reactor/Client.cpp @@ -0,0 +1,118 @@ +/** + * $Id$ + * + * A simple client program using ACE_Svc_Handler and ACE_Connector. + */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_time.h" +#include "Client.h" + +// Listing 2 code/ch07 +int Client::open (void *p) +{ + ACE_Time_Value iter_delay (2); // Two seconds + if (super::open (p) == -1) + return -1; + this->notifier_.reactor (this->reactor ()); + this->msg_queue ()->notification_strategy (&this->notifier_); + this->iterations_ = 0; + return this->reactor ()->schedule_timer + (this, 0, ACE_Time_Value::zero, iter_delay); +} +// Listing 2 + +// Listing 3 code/ch07 +int Client::handle_input (ACE_HANDLE) +{ + char buf[64]; + ssize_t recv_cnt = this->peer ().recv (buf, sizeof (buf) - 1); + if (recv_cnt > 0) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%.*C"), + static_cast<int> (recv_cnt), + buf)); + return 0; + } + + if (recv_cnt == 0 || ACE_OS::last_error () != EWOULDBLOCK) + { + this->reactor ()->end_reactor_event_loop (); + return -1; + } + return 0; +} +// Listing 3 + +// Listing 4 code/ch07 +int Client::handle_timeout(const ACE_Time_Value &, const void *) +{ + if (++this->iterations_ >= ITERATIONS) + { + this->peer ().close_writer (); + return 0; + } + + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (128), -1); + int nbytes = ACE_OS::sprintf + (mb->wr_ptr (), "Iteration %d\n", this->iterations_); + ACE_ASSERT (nbytes > 0); + mb->wr_ptr (static_cast<size_t> (nbytes)); + this->putq (mb); + return 0; +} +// Listing 4 + +// Listing 5 code/ch07 +int Client::handle_output (ACE_HANDLE) +{ + ACE_Message_Block *mb; + ACE_Time_Value nowait (ACE_OS::gettimeofday ()); + while (-1 != this->getq (mb, &nowait)) + { + ssize_t send_cnt = + this->peer ().send (mb->rd_ptr (), mb->length ()); + if (send_cnt == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send"))); + else + mb->rd_ptr (static_cast<size_t> (send_cnt)); + if (mb->length () > 0) + { + this->ungetq (mb); + break; + } + mb->release (); + } + if (this->msg_queue ()->is_empty ()) + this->reactor ()->cancel_wakeup + (this, ACE_Event_Handler::WRITE_MASK); + else + this->reactor ()->schedule_wakeup + (this, ACE_Event_Handler::WRITE_MASK); + return 0; +} +// Listing 5 + +// Listing 6 code/ch07 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_INET_Addr port_to_connect (ACE_TEXT ("HAStatus"), ACE_LOCALHOST); + ACE_Connector<Client, ACE_SOCK_CONNECTOR> connector; + Client client; + Client *pc = &client; + if (connector.connect (pc, port_to_connect) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("connect")), 1); + + ACE_Reactor::instance ()->run_reactor_event_loop (); + return (0); +} +// Listing 6 + +// Listing 7 code/ch07 +// Listing 7 diff --git a/ACE/examples/APG/Reactor/Client.h b/ACE/examples/APG/Reactor/Client.h new file mode 100644 index 00000000000..9aba262151a --- /dev/null +++ b/ACE/examples/APG/Reactor/Client.h @@ -0,0 +1,52 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __CLIENT_H_ +#define __CLIENT_H_ + +#include "ace/Synch_Traits.h" +#include "ace/Null_Condition.h" +#include "ace/Null_Mutex.h" + +// Listing 1 code/ch07 +#include "ace/Reactor.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Connector.h" +#include "ace/Connector.h" +#include "ace/Svc_Handler.h" +#include "ace/Reactor_Notification_Strategy.h" + +class Client : + public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ + typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super; + +public: + Client () : notifier_ (0, this, ACE_Event_Handler::WRITE_MASK) + {} + + virtual int open (void * = 0); + + // Called when input is available from the client. + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when output is possible. + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when a timer expires. + virtual int handle_timeout (const ACE_Time_Value ¤t_time, + const void *act = 0); + +private: + enum { ITERATIONS = 5 }; + int iterations_; + ACE_Reactor_Notification_Strategy notifier_; +}; +// Listing 1 + +#endif /* __CLIENT_H_ */ diff --git a/ACE/examples/APG/Reactor/ClientService.h b/ACE/examples/APG/Reactor/ClientService.h new file mode 100644 index 00000000000..f6ac96e9286 --- /dev/null +++ b/ACE/examples/APG/Reactor/ClientService.h @@ -0,0 +1,40 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __CLIENTSERVICE_H_ +#define __CLIENTSERVICE_H_ + +#include "ace/Synch_Traits.h" +#include "ace/Null_Condition.h" +#include "ace/Null_Mutex.h" + +// Listing 3 code/ch07 +#include "ace/Message_Block.h" +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" + +class ClientService : + public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ + typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super; + +public: + int open (void * = 0); + + // Called when input is available from the client. + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when output is possible. + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when this handler is removed from the ACE_Reactor. + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); +}; +// Listing 3 + +#endif /* __CLIENTSERVICE_H_ */ diff --git a/ACE/examples/APG/Reactor/HAStatus-AC.cpp b/ACE/examples/APG/Reactor/HAStatus-AC.cpp new file mode 100644 index 00000000000..c99a1c5036c --- /dev/null +++ b/ACE/examples/APG/Reactor/HAStatus-AC.cpp @@ -0,0 +1,139 @@ +// $Id$ + +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/os_include/os_netdb.h" +#include "ClientService.h" + +// Listing 1 code/ch07 +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Reactor.h" +#include "ace/Acceptor.h" + +typedef ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR> + ClientAcceptor; +// Listing 1 + +// Listing 4 code/ch07 +int +ClientService::open (void *p) +{ + if (super::open (p) == -1) + return -1; + + ACE_TCHAR peer_name[MAXHOSTNAMELEN]; + ACE_INET_Addr peer_addr; + if (this->peer ().get_remote_addr (peer_addr) == 0 && + peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connection from %s\n"), + peer_name)); + return 0; +} +// Listing 4 + +// Listing 5 code/ch07 +int +ClientService::handle_input (ACE_HANDLE) +{ + const size_t INPUT_SIZE = 4096; + char buffer[INPUT_SIZE]; + ssize_t recv_cnt, send_cnt; + + recv_cnt = this->peer ().recv (buffer, sizeof(buffer)); + if (recv_cnt <= 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connection closed\n"))); + return -1; + } + + send_cnt = + this->peer ().send (buffer, + static_cast<size_t> (recv_cnt)); + if (send_cnt == recv_cnt) + return 0; + if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send")), + 0); + if (send_cnt == -1) + send_cnt = 0; + ACE_Message_Block *mb; + size_t remaining = + static_cast<size_t> ((recv_cnt - send_cnt)); + ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1); + mb->copy (&buffer[send_cnt], remaining); + int output_off = this->msg_queue ()->is_empty (); + ACE_Time_Value nowait (ACE_OS::gettimeofday ()); + if (this->putq (mb, &nowait) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p; discarding data\n"), + ACE_TEXT ("enqueue failed"))); + mb->release (); + return 0; + } + if (output_off) + return this->reactor ()->register_handler + (this, ACE_Event_Handler::WRITE_MASK); + return 0; +} +// Listing 5 + +// Listing 6 code/ch07 +int +ClientService::handle_output (ACE_HANDLE) +{ + ACE_Message_Block *mb; + ACE_Time_Value nowait (ACE_OS::gettimeofday ()); + while (-1 != this->getq (mb, &nowait)) + { + ssize_t send_cnt = + this->peer ().send (mb->rd_ptr (), mb->length ()); + if (send_cnt == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send"))); + else + mb->rd_ptr (static_cast<size_t> (send_cnt)); + if (mb->length () > 0) + { + this->ungetq (mb); + break; + } + mb->release (); + } + return (this->msg_queue ()->is_empty ()) ? -1 : 0; +} +// Listing 6 + +// Listing 7 code/ch07 +int +ClientService::handle_close (ACE_HANDLE h, ACE_Reactor_Mask mask) +{ + if (mask == ACE_Event_Handler::WRITE_MASK) + return 0; + return super::handle_close (h, mask); +} +// Listing 7 + +// Listing 2 code/ch07 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_INET_Addr port_to_listen ("HAStatus"); + ClientAcceptor acceptor; + if (acceptor.open (port_to_listen) == -1) + return 1; + + ACE_Reactor::instance ()->run_reactor_event_loop (); + + return (0); +} +// Listing 2 + +// Listing 8 code/ch07 +// Listing 8 diff --git a/ACE/examples/APG/Reactor/HAStatus.cpp b/ACE/examples/APG/Reactor/HAStatus.cpp new file mode 100644 index 00000000000..fb32aa61632 --- /dev/null +++ b/ACE/examples/APG/Reactor/HAStatus.cpp @@ -0,0 +1,332 @@ +// $Id$ + +#include "ace/OS_NS_sys_time.h" +#include "ace/os_include/os_netdb.h" + +// Listing 1 code/ch07 +#include "ace/Auto_Ptr.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Reactor.h" + +class ClientAcceptor : public ACE_Event_Handler +{ +public: + virtual ~ClientAcceptor (); + + int open (const ACE_INET_Addr &listen_addr); + + // Get this handler's I/O handle. + virtual ACE_HANDLE get_handle (void) const + { return this->acceptor_.get_handle (); } + + // Called when a connection is ready to accept. + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when this handler is removed from the ACE_Reactor. + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); + +protected: + ACE_SOCK_Acceptor acceptor_; +}; +// Listing 1 + +// Listing 6 code/ch07 +#include "ace/Message_Block.h" +#include "ace/Message_Queue.h" +#include "ace/SOCK_Stream.h" +#include "ace/Synch.h" + +class ClientService : public ACE_Event_Handler +{ +public: + ACE_SOCK_Stream &peer (void) { return this->sock_; } + + int open (void); + + // Get this handler's I/O handle. + virtual ACE_HANDLE get_handle (void) const + { return this->sock_.get_handle (); } + + // Called when input is available from the client. + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when output is possible. + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + // Called when this handler is removed from the ACE_Reactor. + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); + +protected: + ACE_SOCK_Stream sock_; + ACE_Message_Queue<ACE_NULL_SYNCH> output_queue_; +}; +// Listing 6 + +// Listing 5 code/ch07 +ClientAcceptor::~ClientAcceptor () +{ + this->handle_close (ACE_INVALID_HANDLE, 0); +} +// Listing 5 + +// Listing 2 code/ch07 +int +ClientAcceptor::open (const ACE_INET_Addr &listen_addr) +{ + if (this->acceptor_.open (listen_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("acceptor.open")), + -1); + return this->reactor ()->register_handler + (this, ACE_Event_Handler::ACCEPT_MASK); +} +// Listing 2 + +// Listing 3 code/ch07 +int +ClientAcceptor::handle_input (ACE_HANDLE) +{ + ClientService *client; + ACE_NEW_RETURN (client, ClientService, -1); + auto_ptr<ClientService> p (client); + + if (this->acceptor_.accept (client->peer ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("Failed to accept ") + ACE_TEXT ("client connection")), + -1); + p.release (); + client->reactor (this->reactor ()); + if (client->open () == -1) + client->handle_close (ACE_INVALID_HANDLE, 0); + return 0; +} +// Listing 3 + +// Listing 4 code/ch07 +int +ClientAcceptor::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE) + { + ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK | + ACE_Event_Handler::DONT_CALL; + this->reactor ()->remove_handler (this, m); + this->acceptor_.close (); + } + return 0; +} +// Listing 4 + +// Listing 7 code/ch07 +int +ClientService::open (void) +{ + ACE_TCHAR peer_name[MAXHOSTNAMELEN]; + ACE_INET_Addr peer_addr; + if (this->sock_.get_remote_addr (peer_addr) == 0 && + peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connection from %s\n"), + peer_name)); + return this->reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK); +} +// Listing 7 + +// Listing 8 code/ch07 +int +ClientService::handle_input (ACE_HANDLE) +{ + const size_t INPUT_SIZE = 4096; + char buffer[INPUT_SIZE]; + ssize_t recv_cnt, send_cnt; + + if ((recv_cnt = this->sock_.recv (buffer, sizeof(buffer))) <= 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connection closed\n"))); + return -1; + } + + send_cnt = + this->sock_.send (buffer, static_cast<size_t> (recv_cnt)); + if (send_cnt == recv_cnt) + return 0; + if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send")), + 0); + if (send_cnt == -1) + send_cnt = 0; + ACE_Message_Block *mb; + size_t remaining = + static_cast<size_t> ((recv_cnt - send_cnt)); + ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1); + mb->copy (&buffer[send_cnt], remaining); + int output_off = this->output_queue_.is_empty (); + ACE_Time_Value nowait (ACE_OS::gettimeofday ()); + if (this->output_queue_.enqueue_tail (mb, &nowait) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p; discarding data\n"), + ACE_TEXT ("enqueue failed"))); + mb->release (); + return 0; + } + if (output_off) + return this->reactor ()->register_handler + (this, ACE_Event_Handler::WRITE_MASK); + return 0; +} +// Listing 8 + +// Listing 9 code/ch07 +int +ClientService::handle_output (ACE_HANDLE) +{ + ACE_Message_Block *mb; + ACE_Time_Value nowait (ACE_OS::gettimeofday ()); + while (0 == this->output_queue_.dequeue_head + (mb, &nowait)) + { + ssize_t send_cnt = + this->sock_.send (mb->rd_ptr (), mb->length ()); + if (send_cnt == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send"))); + else + mb->rd_ptr (static_cast<size_t> (send_cnt)); + if (mb->length () > 0) + { + this->output_queue_.enqueue_head (mb); + break; + } + mb->release (); + } + return (this->output_queue_.is_empty ()) ? -1 : 0; +} +// Listing 9 + +// Listing 10 code/ch07 +int +ClientService::handle_close (ACE_HANDLE, ACE_Reactor_Mask mask) +{ + if (mask == ACE_Event_Handler::WRITE_MASK) + return 0; + mask = ACE_Event_Handler::ALL_EVENTS_MASK | + ACE_Event_Handler::DONT_CALL; + this->reactor ()->remove_handler (this, mask); + this->sock_.close (); + this->output_queue_.flush (); + delete this; + return 0; +} +// Listing 10 + +// Listing 12 code/ch07 +class LoopStopper : public ACE_Event_Handler +{ +public: + LoopStopper (int signum = SIGINT); + + // Called when object is signaled by OS. + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0); +}; + +LoopStopper::LoopStopper (int signum) +{ + ACE_Reactor::instance ()->register_handler (signum, this); +} + +int +LoopStopper::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_Reactor::instance ()->end_reactor_event_loop (); + return 0; +} +// Listing 12 + +// Listing 13 code/ch07 +#include "ace/Signal.h" + +class LogSwitcher : public ACE_Event_Handler +{ +public: + LogSwitcher (int on_sig, int off_sig); + + // Called when object is signaled by OS. + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0); + + // Called when an exceptional event occurs. + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); + +private: + LogSwitcher () {} + + int on_sig_; // Signal to turn logging on + int off_sig_; // Signal to turn logging off + int on_off_; // 1 == turn on, 0 == turn off +}; + +LogSwitcher::LogSwitcher (int on_sig, int off_sig) + : on_sig_ (on_sig), off_sig_ (off_sig) +{ + ACE_Sig_Set sigs; + sigs.sig_add (on_sig); + sigs.sig_add (off_sig); + ACE_Reactor::instance ()->register_handler (sigs, this); +} +// Listing 13 + +// Listing 14 code/ch07 +int +LogSwitcher::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + if (signum == this->on_sig_ || signum == this->off_sig_) + { + this->on_off_ = signum == this->on_sig_; + ACE_Reactor::instance ()->notify (this); + } + return 0; +} +// Listing 14 + +// Listing 15 code/ch07 +int +LogSwitcher::handle_exception (ACE_HANDLE) +{ + if (this->on_off_) + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::SILENT); + else + ACE_LOG_MSG->set_flags (ACE_Log_Msg::SILENT); + return 0; +} +// Listing 15 + +// Listing 11 code/ch07 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_INET_Addr port_to_listen ("HAStatus"); + ClientAcceptor acceptor; + acceptor.reactor (ACE_Reactor::instance ()); + if (acceptor.open (port_to_listen) == -1) + return 1; + + ACE_Reactor::instance ()->run_reactor_event_loop (); + + return (0); +} +// Listing 11 diff --git a/ACE/examples/APG/Reactor/Makefile.am b/ACE/examples/APG/Reactor/Makefile.am new file mode 100644 index 00000000000..789c0ce7785 --- /dev/null +++ b/ACE/examples/APG/Reactor/Makefile.am @@ -0,0 +1,139 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Client.am +noinst_PROGRAMS = Client + +Client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Client_SOURCES = \ + Client.cpp \ + Client.h + +Client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.HAStatus.am +noinst_PROGRAMS += HAStatus + +HAStatus_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HAStatus_SOURCES = \ + HAStatus.cpp \ + Client.h \ + ClientService.h + +HAStatus_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.HAStatus_AC.am +noinst_PROGRAMS += HAStatus-AC + +HAStatus_AC_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HAStatus_AC_SOURCES = \ + HAStatus-AC.cpp \ + Client.h \ + ClientService.h + +HAStatus_AC_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Reactor_Timers.am +noinst_PROGRAMS += Timers + +Timers_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Timers_SOURCES = \ + Timers.cpp \ + Client.h \ + ClientService.h + +Timers_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Reschedule.am +noinst_PROGRAMS += Reschedule + +Reschedule_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Reschedule_SOURCES = \ + Reschedule.cpp \ + Client.h \ + ClientService.h + +Reschedule_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Schedule_Timers.am +noinst_PROGRAMS += Schedule_Timers + +Schedule_Timers_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Schedule_Timers_SOURCES = \ + Schedule_Timers.cpp \ + Client.h \ + ClientService.h + +Schedule_Timers_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Timer_Cancel.am +noinst_PROGRAMS += Timer_Cancel + +Timer_Cancel_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Timer_Cancel_SOURCES = \ + Timer_Cancel.cpp \ + Client.h \ + ClientService.h + +Timer_Cancel_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Timer_State_Data.am +noinst_PROGRAMS += Timer_State_Data + +Timer_State_Data_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Timer_State_Data_SOURCES = \ + Timer_State_Data.cpp \ + Client.h \ + ClientService.h + +Timer_State_Data_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Reactor/Reschedule.cpp b/ACE/examples/APG/Reactor/Reschedule.cpp new file mode 100644 index 00000000000..55ce1f74143 --- /dev/null +++ b/ACE/examples/APG/Reactor/Reschedule.cpp @@ -0,0 +1,83 @@ +/** + * $Id$ + * + * Changing the interval + */ + +#include "ace/OS_NS_time.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Event_Handler.h" + +class MyTimerHandler : public ACE_Event_Handler +{ +public: + int handle_timeout (const ACE_Time_Value ¤t_time, + const void * = 0 ) + { + time_t epoch = ((timespec_t)current_time).tv_sec; + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("handle_timeout: %s"), + ACE_OS::ctime(&epoch))); + return 0; + } + +}; + +// Listing 1 code/ch07 +class SigintHandler : public ACE_Event_Handler +{ +public: + SigintHandler (long timerId, int currentInterval) + : ACE_Event_Handler(), + timerId_(timerId), + currentInterval_(currentInterval) + { + } + + int handle_signal (int, + siginfo_t * = 0, + ucontext_t * = 0) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Resetting interval of timer ") + ACE_TEXT ("%d to %d\n"), + this->timerId_, + ++this->currentInterval_)); + ACE_Time_Value newInterval (this->currentInterval_); + ACE_Reactor::instance()-> + reset_timer_interval (this->timerId_, newInterval); + return 0; + } + +private: + long timerId_; + int currentInterval_; +}; +// Listing 1 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Time_Value initialDelay (3); + ACE_Time_Value interval (5); + + // Listing 2 code/ch07 + MyTimerHandler *handler = new MyTimerHandler (); + + long timerId = + ACE_Reactor::instance ()->schedule_timer (handler, + 0, + initialDelay, + interval); + // Listing 2 + + // Listing 3 code/ch07 + SigintHandler *handleSigint = + new SigintHandler (timerId, 5); + ACE_Reactor::instance ()->register_handler (SIGINT, + handleSigint); + // Listing 3 + + ACE_Reactor::instance ()->run_reactor_event_loop (); + return 0; +} diff --git a/ACE/examples/APG/Reactor/Schedule_Timers.cpp b/ACE/examples/APG/Reactor/Schedule_Timers.cpp new file mode 100644 index 00000000000..5fa57ebfa07 --- /dev/null +++ b/ACE/examples/APG/Reactor/Schedule_Timers.cpp @@ -0,0 +1,65 @@ +/** + * $Id$ + * + * Scheduling timers with the Reactor + */ + +#include "ace/OS_NS_time.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Event_Handler.h" + +// Listing 1 code/ch07 +class MyTimerHandler : public ACE_Event_Handler +{ +public: + int handle_timeout (const ACE_Time_Value ¤t_time, + const void * = 0) + { + time_t epoch = ((timespec_t)current_time).tv_sec; + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("handle_timeout: %s\n"), + ACE_OS::ctime (&epoch))); + + return 0; + } +}; +// Listing 1 + +// Create a SIGINT handler so that we can exit +// the program politely +class SigintHandler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, + ucontext_t * = 0) + { + if (signum == SIGINT) + { + ACE_Reactor::instance ()->end_reactor_event_loop (); + } + return 0; + } +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 2 code/ch07 + MyTimerHandler * timer = new MyTimerHandler (); + ACE_Time_Value initialDelay (3); + ACE_Time_Value interval (5); + ACE_Reactor::instance()->schedule_timer (timer, + 0, + initialDelay, + interval); + // Listing 2 + + // Exclude 1 + SigintHandler * handleExit = new SigintHandler (); + ACE_Reactor::instance()->register_handler (SIGINT, + handleExit); + // Exclude 1 + ACE_Reactor::instance ()->run_reactor_event_loop (); + return 0; +} diff --git a/ACE/examples/APG/Reactor/Timer_Cancel.cpp b/ACE/examples/APG/Reactor/Timer_Cancel.cpp new file mode 100644 index 00000000000..3e6a0f2ec61 --- /dev/null +++ b/ACE/examples/APG/Reactor/Timer_Cancel.cpp @@ -0,0 +1,106 @@ +/** + * $Id$ + * + * Changing the interval and canceling + */ + +#include "ace/OS_NS_time.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Event_Handler.h" + +class MyTimerHandler : public ACE_Event_Handler +{ +public: + int handle_timeout (const ACE_Time_Value ¤t_time, + const void * = 0) + { + time_t epoch = ((timespec_t)current_time).tv_sec; + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("handle_timeout: %s"), + ACE_OS::ctime(&epoch))); + return 0; + } + +}; + +#if !defined (ACE_LACKS_UNIX_SIGNALS) + +// Listing 1 code/ch07 +class SignalHandler : public ACE_Event_Handler +{ +public: + SignalHandler (long timerId, int currentInterval) + : ACE_Event_Handler(), + timerId_(timerId), + currentInterval_(currentInterval) + { + } + + int handle_signal (int sig, + siginfo_t * = 0, + ucontext_t * = 0) + { + if (sig == SIGINT) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Resetting interval of timer ") + ACE_TEXT ("%d to %d\n"), + this->timerId_, + ++this->currentInterval_)); + ACE_Time_Value newInterval (this->currentInterval_); + ACE_Reactor::instance ()-> + reset_timer_interval (this->timerId_, newInterval); + } + else if (sig == SIGTSTP) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Canceling timer %d\n"), + this->timerId_)); + ACE_Reactor::instance ()->cancel_timer (this->timerId_); + } + + return 0; + } + +private: + long timerId_; + int currentInterval_; +}; +// Listing 1 + +#endif /* ACE_LACKS_UNIX_SIGNALS */ + + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Time_Value initialDelay (3); + ACE_Time_Value interval (5); + + // Listing 2 code/ch07 + MyTimerHandler *handler = new MyTimerHandler (); + long timerId = + ACE_Reactor::instance ()->schedule_timer (handler, + 0, + initialDelay, + interval); + // Listing 2 + +#if !defined (ACE_LACKS_UNIX_SIGNALS) + + // Listing 3 code/ch07 + SignalHandler *mutateTimer = + new SignalHandler (timerId, 5); + ACE_Reactor::instance ()->register_handler (SIGINT, + mutateTimer); + ACE_Reactor::instance ()->register_handler (SIGTSTP, + mutateTimer); + // Listing 3 + +#else + ACE_UNUSED_ARG (timerId); +#endif /* ACE_LACKS_UNIX_SIGNALS */ + + ACE_Reactor::instance ()->run_reactor_event_loop (); + return 0; +} diff --git a/ACE/examples/APG/Reactor/Timer_State_Data.cpp b/ACE/examples/APG/Reactor/Timer_State_Data.cpp new file mode 100644 index 00000000000..215381df394 --- /dev/null +++ b/ACE/examples/APG/Reactor/Timer_State_Data.cpp @@ -0,0 +1,153 @@ +/** + * $Id$ + * + * Reactor examples + * + * Timers & state data + */ + +#include "ace/OS_NS_time.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Event_Handler.h" + +// Listing 0 code/ch07 +class TemperatureSensor +{ +public: + TemperatureSensor (const char *location) + : location_(location), + count_(0), + temperature_(0.0) + // ... + { } + + const char *location () const + { + return this->location_; + } + + int querySensor (void) + { + // ... + return ++this->count_; + } + + float temperature (void) const + { + return this->temperature_; + } + +private: + const char *location_; + int count_; + float temperature_; + // ... +}; +// Listing 0 + +// Listing 1 code/ch07 +class TemperatureQueryHandler : public ACE_Event_Handler +{ +public: + TemperatureQueryHandler () + : ACE_Event_Handler(), + counter_(0), + averageTemperature_(0.0) + // ... + { + } + + int handle_timeout (const ACE_Time_Value ¤t_time, + const void *arg) + { + time_t epoch = ((timespec_t)current_time).tv_sec; + + const TemperatureSensor *const_sensor = + reinterpret_cast<const TemperatureSensor *> (arg); + TemperatureSensor *sensor = + const_cast<TemperatureSensor *> (const_sensor); + + int queryCount = sensor->querySensor (); + this->updateAverageTemperature (sensor); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("%s\t") + ACE_TEXT ("%d/%d\t") + ACE_TEXT ("%.2f/%.2f\t") + ACE_TEXT ("%s\n"), + sensor->location (), + ++this->counter_, + queryCount, + this->averageTemperature_, + sensor->temperature (), + ACE_OS::ctime(&epoch))); + return 0; + } + +private: + void updateAverageTemperature (TemperatureSensor *) + { + // ... + } + + int counter_; + float averageTemperature_; +}; +// Listing 1 + +// Create a SIGINT handler so that we can exit +// the program politely +class SigintHandler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, + ucontext_t * = 0) + { + if (signum == SIGINT) + { + ACE_Reactor::instance ()->end_reactor_event_loop (); + } + return 0; + } +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 2 code/ch07 + TemperatureQueryHandler *temperatureMonitor = + new TemperatureQueryHandler (); + // Listing 2 + + ACE_Time_Value initialDelay (3); + ACE_Time_Value intervalOne (5); + // Listing 3 code/ch07 + TemperatureSensor *sensorOne = + new TemperatureSensor ("Kitchen"); + + ACE_Reactor::instance ()->schedule_timer (temperatureMonitor, + sensorOne, + initialDelay, + intervalOne); + // Listing 3 + + ACE_Time_Value intervalTwo (4); + // Listing 4 code/ch07 + TemperatureSensor *sensorTwo = + new TemperatureSensor ("Foyer"); + + ACE_Reactor::instance ()->schedule_timer (temperatureMonitor, + sensorTwo, + initialDelay, + intervalTwo); + // Listing 4 + + SigintHandler *handleExit = new SigintHandler (); + + ACE_Reactor::instance ()->register_handler (SIGINT, + handleExit); + + ACE_Reactor::instance ()->run_reactor_event_loop (); + + return 0; +} diff --git a/ACE/examples/APG/Reactor/Timers.cpp b/ACE/examples/APG/Reactor/Timers.cpp new file mode 100644 index 00000000000..c603b86bef4 --- /dev/null +++ b/ACE/examples/APG/Reactor/Timers.cpp @@ -0,0 +1,81 @@ +// $Id$ + +#include "ace/config-all.h" +#include "ace/OS_main.h" + +#if !defined (ACE_LACKS_FORK) + +#include "ace/streams.h" + +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> +#include <time.h> + +typedef void (*timerTask_t)(void); + +// Listing 1 code/ch07 +pid_t timerTask (int initialDelay, + int interval, + timerTask_t task) +{ + if (initialDelay < 1 && interval < 1) + return -1; + + pid_t pid = fork (); + + if (pid < 0) + return -1; + + if (pid > 0) + return pid; + + if (initialDelay > 0) + sleep (initialDelay); + + if (interval < 1) + return 0; + + while (1) + { + (*task) (); + sleep (interval); + } + + ACE_NOTREACHED (return 0); +} +// Listing 1 + +// Listing 2 code/ch07 +void foo () +{ + time_t now = time (0); + cerr << "The time is " << ctime (&now) << endl; +} +// Listing 2 + +void programMainLoop (void) +{ + sleep (30); +} + +// Listing 3 code/ch07 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + pid_t timerId = timerTask (3, 5, foo); + programMainLoop (); + kill (timerId, SIGINT); + return 0; +} +// Listing 3 + +#else +#include <stdio.h> + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + puts ("This very unportable example requires fork().\n"); + return 0; +} + +#endif /* ACE_LACKS_FORK */ diff --git a/ACE/examples/APG/Reactor/reactor.mpc b/ACE/examples/APG/Reactor/reactor.mpc new file mode 100644 index 00000000000..7454f9d5c9f --- /dev/null +++ b/ACE/examples/APG/Reactor/reactor.mpc @@ -0,0 +1,58 @@ +// -*- MPC -*- +// $Id$ + +project(Client) : aceexe { + exename = Client + Source_Files { + Client.cpp + } +} + +project(HAStatus) : aceexe { + exename = HAStatus + Source_Files { + HAStatus.cpp + } +} + +project(HAStatus AC) : aceexe { + exename = HAStatus-AC + Source_Files { + HAStatus-AC.cpp + } +} + +project(Reschedule) : aceexe { + exename = Reschedule + Source_Files { + Reschedule.cpp + } +} + +project(Schedule Timers) : aceexe { + exename = Schedule_Timers + Source_Files { + Schedule_Timers.cpp + } +} + +project(Timer Cancel) : aceexe { + exename = Timer_Cancel + Source_Files { + Timer_Cancel.cpp + } +} + +project(*Timers) : aceexe { + exename = Timers + Source_Files { + Timers.cpp + } +} + +project(Timer State Data) : aceexe { + exename = Timer_State_Data + Source_Files { + Timer_State_Data.cpp + } +} diff --git a/ACE/examples/APG/Shared_Memory/.cvsignore b/ACE/examples/APG/Shared_Memory/.cvsignore new file mode 100644 index 00000000000..4fbe7c66db3 --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/.cvsignore @@ -0,0 +1,10 @@ +Hash_Map +Hash_Map +Malloc +Malloc +Mem_Map +Mem_Map +PI_Malloc +PI_Malloc +Pool_Growth +Pool_Growth diff --git a/ACE/examples/APG/Shared_Memory/Hash_Map.cpp b/ACE/examples/APG/Shared_Memory/Hash_Map.cpp new file mode 100644 index 00000000000..b8d73e0045c --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Hash_Map.cpp @@ -0,0 +1,250 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" + +// Listing 1 code/ch17 +#include "ace/MMAP_Memory_Pool.h" +#include "ace/Hash_Map_With_Allocator_T.h" +#include "ace/Malloc_T.h" +#include "ace/PI_Malloc.h" +#include "ace/Process_Mutex.h" +#include "ace/Process.h" + +#define BACKING_STORE "map.store" +#define MAP_NAME "records.db" + +#include "Record.h" + +typedef ACE_Allocator_Adapter<ACE_Malloc_T <ACE_MMAP_MEMORY_POOL, + ACE_Process_Mutex, + ACE_Control_Block> + > ALLOCATOR; +typedef ACE_Hash_Map_With_Allocator<int, Record> HASH_MAP; + +ACE_Process_Mutex coordMutex("Coord-Mutex"); +// Listing 1 + +// Listing 2 code/ch17 +HASH_MAP* smap (ALLOCATOR *shmem_allocator) +{ + void *db = 0; + if (shmem_allocator->find (MAP_NAME, db) == 0) + return (HASH_MAP *) db; + size_t hash_table_size = sizeof (HASH_MAP); + void *hash_map = shmem_allocator->malloc (hash_table_size); + if (hash_map == 0) + return 0; + new (hash_map) HASH_MAP (hash_table_size, shmem_allocator); + if (shmem_allocator->bind (MAP_NAME, hash_map) == -1) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("allocate_map"))); + shmem_allocator->remove (); + return 0; + } + return (HASH_MAP*)hash_map; +} +// Listing 2 +// Listing 6 code/ch17 +int processRecords (HASH_MAP *map, ALLOCATOR *shmem_allocator) +{ + ACE_TRACE ("processRecords"); + + size_t mapLength = map->current_size (); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Found %d records\n\n"), + mapLength)); + + int *todelete = new int[mapLength]; + int i = 0; + + for (HASH_MAP::iterator iter = map->begin (); + iter != map->end (); + iter++) + { + int key = (*iter).ext_id_; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) [%d] Preprocessing %d:%@\n"), + i+1, key, &(*iter).ext_id_)); + + todelete[i++] = key; // Mark message for deletion. + + // Illustrate the find feature of the map. + Record record; + int result = map->find (key, record, shmem_allocator); + if (result == -1) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("Could not find record for %d\n"), + key)); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Record name: %C|id1:%d|id2:%d\n"), + record.name (), record.id1(), record.id2())); + } + + // Delete everything we processed. + for (int j = 0; j < i ; j++) + { + int result = map->unbind (todelete[j], + shmem_allocator); + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed on key %d: %p\n"), + ACE_TEXT ("unbind"), + todelete[j]), + -1); + else + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Fully processed and removed %d\n"), + j)); + } + + delete [] todelete; + + return 0; +} +// Listing 6 +// Listing 4 code/ch17 +int addRecords(HASH_MAP *map, ALLOCATOR *shmem_allocator) +{ + ACE_TRACE ("addRecords"); + + char buf[32]; + int mapLength = static_cast<int> (map->current_size ()); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Map has %d entries; adding 20 more\n"), + mapLength)); + + for (int i = mapLength ; i < mapLength + 20; i++) + { + ACE_OS::sprintf (buf, "%s:%d", "Record", i); + + // Allocate new record on stack; + Record newRecord (i, i+1, buf); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Adding a record for %d\n"), i)); + + int result = map->bind (i, newRecord, shmem_allocator); + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("bind failed")), -1); + } + + return 0; +} +// Listing 4 +// Listing 5 code/ch17 +int handle_child (void) +{ + ACE_TRACE ("handle_child"); + + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, coordMutex, -1); + + ALLOCATOR * shmem_allocator = 0; + ACE_MMAP_Memory_Pool_Options options + (ACE_DEFAULT_BASE_ADDR, + ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED); + + ACE_NEW_RETURN (shmem_allocator, + ALLOCATOR (BACKING_STORE, + BACKING_STORE, + &options), + -1); + + HASH_MAP *map = smap (shmem_allocator); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Map has %d entries\n"), + map->current_size ())); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("In child, map is located at %@\n"), + map)); + + processRecords (map, shmem_allocator); + shmem_allocator->sync (); + delete shmem_allocator; + + return 0; +} +// Listing 5 +// Listing 3 code/ch17 +int handle_parent (ACE_TCHAR *cmdLine) +{ + ACE_TRACE ("handle_parent"); + + ALLOCATOR * shmem_allocator = 0; + ACE_MMAP_Memory_Pool_Options options + (ACE_DEFAULT_BASE_ADDR, + ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED); + + ACE_NEW_RETURN + (shmem_allocator, + ALLOCATOR (BACKING_STORE, BACKING_STORE, &options), + -1); + + HASH_MAP *map = smap (shmem_allocator); + + ACE_Process processa, processb; + ACE_Process_Options poptions; + const ACE_TCHAR *args[3]; + args[0] = cmdLine; + args[1] = ACE_TEXT ("a"); + args[2] = 0; + poptions.command_line (args); + { + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, + coordMutex, -1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Map has %d entries\n"), + map->current_size ())); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("In parent, map is located at %@\n"), + map)); + + // Then have the child show and eat them up. + processa.spawn (poptions); + + // First append a few records. + addRecords (map, shmem_allocator); + } + + + { + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, + coordMutex, -1); + + // Add a few more records.. + addRecords (map, shmem_allocator); + + // Let's see what's left. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Parent finished adding, ") + ACE_TEXT ("map has %d entries\n"), + map->current_size ())); + + // Have another child try to eat them up. + processb.spawn (poptions); + } + + processa.wait (); + processb.wait (); + + // No processes are left and we don't want to keep the data + // around anymore; it's now safe to remove it. + // !!This will remove the backing store.!! + shmem_allocator->remove (); + delete shmem_allocator; + return 0; +} + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc == 1) // parent + ACE_ASSERT (handle_parent (argv[0]) == 0); + else + ACE_ASSERT (handle_child () == 0); + + ACE_UNUSED_ARG (argv); + return 0; +} +// Listing 3 diff --git a/ACE/examples/APG/Shared_Memory/Makefile.am b/ACE/examples/APG/Shared_Memory/Makefile.am new file mode 100644 index 00000000000..b114eb0153a --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Makefile.am @@ -0,0 +1,112 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Malloc.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Malloc + +Malloc_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Malloc_SOURCES = \ + Malloc.cpp \ + Record.h + +Malloc_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Mem_Map.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Mem_Map + +Mem_Map_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Mem_Map_SOURCES = \ + Mem_Map.cpp \ + Record.h + +Mem_Map_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.PI_Malloc.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += PI_Malloc + +PI_Malloc_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +PI_Malloc_SOURCES = \ + PI_Malloc.cpp \ + Record.h + +PI_Malloc_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Pool_Growth.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Pool_Growth + +Pool_Growth_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Pool_Growth_SOURCES = \ + Pool_Growth.cpp \ + Record.h + +Pool_Growth_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Shared_Memory_Hash_Map.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Hash_Map + +Hash_Map_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Hash_Map_SOURCES = \ + Hash_Map.cpp \ + Record.h + +Hash_Map_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Shared_Memory/Malloc.cpp b/ACE/examples/APG/Shared_Memory/Malloc.cpp new file mode 100644 index 00000000000..7f1ef3a3579 --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Malloc.cpp @@ -0,0 +1,113 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +// Listing 1 code/ch17 +#include "ace/MMAP_Memory_Pool.h" +#include "ace/Malloc_T.h" +#include "ace/Null_Mutex.h" + +typedef ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex> + ALLOCATOR; +typedef ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, + ACE_Null_Mutex> + MALLOC_LIFO_ITERATOR; + +ALLOCATOR *g_allocator; +// Listing 1 + +// Listing 2 code/ch17 +class Record +{ +public: + Record (int id1, int id2, char *name) + : id1_(id1), id2_(id2), name_(0) + { + size_t len = ACE_OS::strlen (name) + 1; + this->name_ = + reinterpret_cast<char *> (g_allocator->malloc (len)); + ACE_OS::strcpy (this->name_, name); + } + + ~Record () { g_allocator->free (name_); } + char* name(void) { return name_; } + int id1 (void) { return id1_; } + int id2 (void) { return id2_; } + +private: + int id1_; + int id2_; + char *name_; +}; +// Listing 2 +// Listing 5 code/ch17 +void showRecords () +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("The following records were found:\n"))); + { + MALLOC_LIFO_ITERATOR iter (*g_allocator); + + for (void *temp = 0; iter.next (temp) != 0; iter.advance ()) + { + Record *record = + reinterpret_cast<Record *> (temp); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Record name: %C|id1:%d|id2:%d\n"), + record->name (), + record->id1 (), + record->id2 ())); + } + } +} +// Listing 5 +// Listing 3 code/ch17 +int addRecords () +{ + char buf[32]; + + for (int i = 0; i < 10; i++) + { + ACE_OS::sprintf (buf, "%s:%d", "Record", i); + void *memory = g_allocator->malloc (sizeof (Record)); + if (memory == 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Unable to malloc")), + -1); + + // Allocate and place record + Record* newRecord = new (memory) Record (i, i+1, buf); + if (g_allocator->bind (buf, newRecord) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("bind failed")), + -1); + } + + return 0; +} +// Listing 3 +// Listing 4 code/ch17 +// Backing file where the data is kept. +#define BACKING_STORE ACE_TEXT("backing.store") + +int ACE_TMAIN (int argc, ACE_TCHAR *[]) +{ + ACE_NEW_RETURN (g_allocator, + ALLOCATOR (BACKING_STORE), + -1); + if (argc > 1) + { + showRecords (); + } + else + { + addRecords (); + } + + g_allocator->sync (); + delete g_allocator; + return 0; +} +// Listing 4 + diff --git a/ACE/examples/APG/Shared_Memory/Mem_Map.cpp b/ACE/examples/APG/Shared_Memory/Mem_Map.cpp new file mode 100644 index 00000000000..c96cd0b0f45 --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Mem_Map.cpp @@ -0,0 +1,35 @@ +// $Id$ + +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_string.h" +#include "ace/Mem_Map.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch17 +int ACE_TMAIN (int, ACE_TCHAR *argv[]) +{ + ACE_HANDLE srcHandle = ACE_OS::open (argv[1], O_RDONLY); + ACE_ASSERT(srcHandle != ACE_INVALID_HANDLE); + + ACE_Mem_Map srcMap (srcHandle, -1, PROT_READ, ACE_MAP_PRIVATE); + ACE_ASSERT(srcMap.addr () != 0); + + ACE_Mem_Map destMap (argv[2], + srcMap.size (), + O_RDWR | O_CREAT, + ACE_DEFAULT_FILE_PERMS, + PROT_RDWR, + ACE_MAP_SHARED); + ACE_ASSERT(destMap.addr () != 0); + + ACE_OS::memcpy (destMap.addr (), + srcMap.addr (), + srcMap.size ()); + destMap.sync (); + + srcMap.close (); + destMap.close (); + return 0; +} +// Listing 1 + diff --git a/ACE/examples/APG/Shared_Memory/PI_Malloc.cpp b/ACE/examples/APG/Shared_Memory/PI_Malloc.cpp new file mode 100644 index 00000000000..2d31ba96f35 --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/PI_Malloc.cpp @@ -0,0 +1,140 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +// Listing 1 code/ch17 +#include "ace/MMAP_Memory_Pool.h" +#include "ace/Malloc_T.h" +#include "ace/Null_Mutex.h" +#include "ace/PI_Malloc.h" + +typedef ACE_Malloc_T <ACE_MMAP_MEMORY_POOL, + ACE_Null_Mutex, + ACE_PI_Control_Block> + ALLOCATOR; +typedef ACE_Malloc_LIFO_Iterator_T<ACE_MMAP_MEMORY_POOL, + ACE_Null_Mutex, + ACE_PI_Control_Block> + MALLOC_LIFO_ITERATOR; + +ALLOCATOR *g_allocator; +// Listing 1 +// Listing 2 code/ch17 +class Record +{ +public: + Record (int id1, int id2, char *name) + : id1_(id1), id2_(id2) + { + size_t len = ACE_OS::strlen (name) + 1; + char *buf = + reinterpret_cast<char *> (g_allocator->malloc (len)); + ACE_OS::strcpy (buf, name); + name_ = buf; + } + + ~Record() { g_allocator->free (name_.addr ()); } + + char *name (void) { return name_; } + int id1 (void) { return id1_; } + int id2 (void) { return id2_; } + +private: + int id1_; + int id2_; + ACE_Based_Pointer_Basic<char> name_; +}; +// Listing 2 + +void showRecords (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("The following records were found:\n"))); + + { + MALLOC_LIFO_ITERATOR iter (*g_allocator); + + for (void *temp = 0; iter.next (temp) != 0; iter.advance ()) + { + Record *record = + reinterpret_cast<Record *> (temp); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Record name: %C|id1:%d|id2:%d\n"), + record->name(), record->id1(), record->id2())); + } + } +} + +int addRecords (void) +{ + char buf[32]; + + for (int i = 0; i < 10; i++) + { + ACE_OS::sprintf (buf, "%s:%d", "Record", i); + + void *memory = g_allocator->malloc (sizeof (Record)); + if (memory == NULL) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Unable to malloc")), + -1); + + // Allocate and place record + Record* newRecord = new (memory) Record (i, i+1, buf); + if (g_allocator->bind (buf, newRecord) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("bind failed")), + -1); + } + + return 0; +} + +// Listing 3 code/ch17 +// Backing file where the data is kept. +#define BACKING_STORE ACE_TEXT("backing2.store") + +int ACE_TMAIN (int argc, ACE_TCHAR *[]) +{ + if (argc > 1) + { + ACE_MMAP_Memory_Pool_Options options + (ACE_DEFAULT_BASE_ADDR, + ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED); + ACE_NEW_RETURN (g_allocator, + ALLOCATOR (BACKING_STORE, + BACKING_STORE, + &options), + -1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Mapped to base address %@\n"), + g_allocator->base_addr ())); + + showRecords (); + } + else + { + ACE_MMAP_Memory_Pool_Options options + (0, ACE_MMAP_Memory_Pool_Options::NEVER_FIXED); + ACE_NEW_RETURN (g_allocator, + ALLOCATOR (BACKING_STORE, + BACKING_STORE, + &options), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Mapped to base address %@\n"), + g_allocator->base_addr ())); + + addRecords(); + } + + g_allocator->sync (); + delete g_allocator; + return 0; +} +// Listing 3 + diff --git a/ACE/examples/APG/Shared_Memory/Pool_Growth.cpp b/ACE/examples/APG/Shared_Memory/Pool_Growth.cpp new file mode 100644 index 00000000000..c354b098242 --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Pool_Growth.cpp @@ -0,0 +1,261 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Malloc_T.h" +#include "ace/PI_Malloc.h" +#include "ace/Process_Mutex.h" +#include "ace/Process.h" +#include "ace/Unbounded_Queue.h" +#include "ace/MMAP_Memory_Pool.h" + +#define BACKING_STORE "queue.dat" +#define QUEUE_NAME "queue.db" + +typedef ACE_Allocator_Adapter<ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> > ALLOCATOR; + +ACE_Process_Mutex coordMutex("Coord-Mutex"); + +// Listing 1 code/ch17 +template <class T> +class Unbounded_Queue : public ACE_Unbounded_Queue<T> +{ +public: + typedef ACE_Unbounded_Queue<T> BASE; + + Unbounded_Queue(ACE_Allocator* allocator) + : ACE_Unbounded_Queue<T> (allocator) + { } + + int enqueue_tail (const T &new_item, ACE_Allocator* allocator) + { + this->allocator_ = allocator; + return BASE::enqueue_tail (new_item); + } + + int dequeue_head (T &item, ACE_Allocator* allocator) + { + this->allocator_ = allocator; + return BASE::dequeue_head (item); + } + + void delete_nodes (ACE_Allocator* allocator) + { + this->allocator_ = allocator; + delete_nodes (); + } +}; +// Listing 1 + +#include "Record.h" + +typedef Unbounded_Queue<Record> QUEUE; + +QUEUE* squeue(ALLOCATOR* shmem_allocator) +{ + void *queue = 0; + + // This is the easy case since if we find hash table in the + // memory-mapped file we know it's already initialized. + if (shmem_allocator->find (QUEUE_NAME, queue) == 0) + return (QUEUE *) queue; + + // Create a new map (because we've just created a new + // memory-mapped file). + size_t queue_size = sizeof (QUEUE); + + queue = shmem_allocator->malloc (queue_size); + + // If allocation failed ... + if (queue == 0) + return 0; + + new (queue) QUEUE (shmem_allocator); + + if (shmem_allocator->bind (QUEUE_NAME, queue) == -1) + { + // Attempt to clean up. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("squeue bind\n"))); + shmem_allocator->remove(); + + return 0; + } + + return (QUEUE*)queue; +} + +static ALLOCATOR * g_shmem_allocator = 0; + +// Listing 4 code/ch17 +int processRecord (ALLOCATOR *shmem_allocator) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, coordMutex, -1); + + QUEUE* queue = squeue (shmem_allocator); + if (queue == 0) + { + delete shmem_allocator; + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Could not obtain queue")), + -1); + } + + if (queue->is_empty ()) // Check for anything to process. + return 0; + + Record record; + if (queue->dequeue_head (record, shmem_allocator) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("dequeue_head\n")), + -1); + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Processing record|name: %C") + ACE_TEXT ("|Record id1:%d|Record id2:%d\n"), + record.name (), record.id1 (), record.id2 ())); + if (record.id1 () == -1) + queue->enqueue_tail (record, shmem_allocator); + return record.id1 (); +} +// Listing 4 +// Listing 5 code/ch17 +#if defined(WIN32) + +int handle_remap (EXCEPTION_POINTERS *ep) +{ + ACE_DEBUG ((LM_INFO, ACE_TEXT ("Handle a remap\n"))); + + DWORD ecode = ep->ExceptionRecord->ExceptionCode; + if (ecode != EXCEPTION_ACCESS_VIOLATION) + return EXCEPTION_CONTINUE_SEARCH; + + void *addr = + (void *) ep->ExceptionRecord->ExceptionInformation[1]; + if (g_shmem_allocator->alloc().memory_pool().remap (addr) == -1) + return EXCEPTION_CONTINUE_SEARCH; +#if __X86__ + // This is 80x86-specific. + ep->ContextRecord->Edi = (DWORD) addr; +#elif __MIPS__ + ep->ContextRecord->IntA0 = + ep->ContextRecord->IntV0 = (DWORD) addr; + ep->ContextRecord->IntT5 = + ep->ContextRecord->IntA0 + 3; +#endif /* __X86__ */ + + return EXCEPTION_CONTINUE_EXECUTION; +} + +int processWin32Record (ALLOCATOR *shmem_allocator) +{ + ACE_SEH_TRY + { + return processRecord (shmem_allocator); + } + + ACE_SEH_EXCEPT (handle_remap (GetExceptionInformation ())) + { } + + return 0; +} +#endif /*WIN32*/ +// Listing 5 + +int sendRecord (int recordId, ALLOCATOR *shmem_allocator) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, coordMutex, -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Sending record %d\n"), + recordId)); + + QUEUE * queue = squeue (shmem_allocator); + char buf[128]; + ACE_OS::sprintf (buf, "%s:%d", "Record", recordId); + Record newRecord (recordId, recordId+1, buf); + + int result = queue->enqueue_tail (newRecord, shmem_allocator); + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("enqueue failed\n")), + -1); + return 0; +} + +// Listing 2 code/ch17 +int handle_parent (ACE_TCHAR *cmdLine) +{ + ALLOCATOR *shmem_allocator = 0; + ACE_MMAP_Memory_Pool_Options options + (ACE_DEFAULT_BASE_ADDR, + ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED); + + // Create the allocator. + ACE_NEW_RETURN (shmem_allocator, + ALLOCATOR (BACKING_STORE, + BACKING_STORE, + &options), + -1); + + ACE_Process processa, processb; + ACE_Process_Options poptions; + const ACE_TCHAR *args[3]; + args[0] = cmdLine; + args[1] = ACE_TEXT ("a"); + args[2] = 0; + poptions.command_line (args); + processa.spawn (poptions); + processb.spawn (poptions); + + // Make sure the child does map a partial pool in memory. + ACE_OS::sleep (2); + + for (int i = 0; i < 100; i++) + sendRecord (i, shmem_allocator); + sendRecord (-1, shmem_allocator); + + processa.wait (); + processb.wait (); + shmem_allocator->remove (); + return 0; +} +// Listing 2 + +// Listing 3 code/ch17 +int handle_child (void) +{ + ALLOCATOR *shmem_allocator = 0; + ACE_MMAP_Memory_Pool_Options options + (ACE_DEFAULT_BASE_ADDR, + ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED); + ACE_NEW_RETURN (shmem_allocator, + ALLOCATOR (BACKING_STORE, + BACKING_STORE, + &options), + -1); + g_shmem_allocator = shmem_allocator; + +#if defined (WIN32) + while (processWin32Record (shmem_allocator) != -1) + ; +#else + while (processRecord (shmem_allocator) != -1) + ; +#endif + return 0; +} +// Listing 3 + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc == 1) + handle_parent(argv[0]); + else + handle_child(); + + return 0; +} + diff --git a/ACE/examples/APG/Shared_Memory/Record.h b/ACE/examples/APG/Shared_Memory/Record.h new file mode 100644 index 00000000000..f3a63e1298b --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/Record.h @@ -0,0 +1,45 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __RECORD_H_ +#define __RECORD_H_ + +#include "ace/OS_NS_string.h" +#include "ace/Based_Pointer_T.h" + +// Listing 11 code/ch17 +class Record +{ +public: + Record () { } + ~Record () { } + + Record (const Record& rec) + : id1_(rec.id1_), id2_(rec.id2_) + { + ACE_OS::strcpy (recName_, rec.name_); + this->name_ = recName_; + } + Record (int id1, int id2, char *name) + : id1_(id1), id2_(id2) + { + ACE_OS::strcpy (recName_, name); + this->name_ = recName_; + } + char *name (void) { return recName_; } + int id1 (void) { return id1_; } + int id2 (void) { return id2_; } + +private: + int id1_; + int id2_; + char recName_[128]; + ACE_Based_Pointer_Basic<char> name_; +}; +// Listing 11 + +#endif /* __RECORD_H_ */ diff --git a/ACE/examples/APG/Shared_Memory/shared_memory.mpc b/ACE/examples/APG/Shared_Memory/shared_memory.mpc new file mode 100644 index 00000000000..2cf2400ef8e --- /dev/null +++ b/ACE/examples/APG/Shared_Memory/shared_memory.mpc @@ -0,0 +1,42 @@ +// -*- MPC -*- +// $Id$ + +project(*Hash Map) : aceexe { + avoids += ace_for_tao + exename = Hash_Map + Source_Files { + Hash_Map.cpp + } +} + +project(Malloc) : aceexe { + avoids += ace_for_tao + exename = Malloc + Source_Files { + Malloc.cpp + } +} + +project(Mem Map) : aceexe { + avoids += ace_for_tao + exename = Mem_Map + Source_Files { + Mem_Map.cpp + } +} + +project(PI Malloc) : aceexe { + avoids += ace_for_tao + exename = PI_Malloc + Source_Files { + PI_Malloc.cpp + } +} + +project(Pool Growth) : aceexe { + avoids += ace_for_tao + exename = Pool_Growth + Source_Files { + Pool_Growth.cpp + } +} diff --git a/ACE/examples/APG/Signals/.cvsignore b/ACE/examples/APG/Signals/.cvsignore new file mode 100644 index 00000000000..23774a5d6a0 --- /dev/null +++ b/ACE/examples/APG/Signals/.cvsignore @@ -0,0 +1,10 @@ +SigAction +SigAction +SigGuard +SigGuard +SigHandler +SigHandler +SigHandlers +SigHandlers +SigInfo +SigInfo diff --git a/ACE/examples/APG/Signals/Makefile.am b/ACE/examples/APG/Signals/Makefile.am new file mode 100644 index 00000000000..ffc67bdd0f0 --- /dev/null +++ b/ACE/examples/APG/Signals/Makefile.am @@ -0,0 +1,85 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.SigAction.am +noinst_PROGRAMS = SigAction + +SigAction_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +SigAction_SOURCES = \ + SigAction.cpp + +SigAction_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SigGuard.am +noinst_PROGRAMS += SigGuard + +SigGuard_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +SigGuard_SOURCES = \ + SigGuard.cpp + +SigGuard_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SigHandler.am +noinst_PROGRAMS += SigHandler + +SigHandler_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +SigHandler_SOURCES = \ + SigHandler.cpp + +SigHandler_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SigHandlers.am +noinst_PROGRAMS += SigHandlers + +SigHandlers_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +SigHandlers_SOURCES = \ + SigHandlers.cpp + +SigHandlers_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SigInfo.am +noinst_PROGRAMS += SigInfo + +SigInfo_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +SigInfo_SOURCES = \ + SigInfo.cpp + +SigInfo_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Signals/SigAction.cpp b/ACE/examples/APG/Signals/SigAction.cpp new file mode 100644 index 00000000000..6d818ae9400 --- /dev/null +++ b/ACE/examples/APG/Signals/SigAction.cpp @@ -0,0 +1,75 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/Log_Msg.h" +// Listing 1 code/ch11 +#include "ace/Signal.h" + +// Forward declaration. +static void register_actions (); + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TRACE (ACE_TEXT ("::main")); + + ::register_actions (); // Register actions to happen. + + // This will be raised immediately. + ACE_OS::kill (ACE_OS::getpid(), SIGUSR2); + + // This will pend until the first signal is completely + // handled and returns, because we masked it out + // in the registerAction call. + ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); + + while (ACE_OS::sleep (100) == -1) + { + if (errno == EINTR) + continue; + else + ACE_OS::exit (1); + } + return 0; +} +// Listing 1 +#if defined (ACE_HAS_SIG_C_FUNC) +extern "C" { +#endif +// Listing 3 code/ch11 +static void my_sighandler (int signo) +{ + ACE_TRACE (ACE_TEXT ("::my_sighandler")); + + ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); + + if (signo == SIGUSR1) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal SIGUSR1\n"))); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal SIGUSR2\n"))); + + ACE_OS::sleep (10); +} +#if defined (ACE_HAS_SIG_C_FUNC) +} +#endif +// Listing 3 +// Listing 2 code/ch11 +static void register_actions () +{ + ACE_TRACE (ACE_TEXT ("::register_actions")); + + ACE_Sig_Action sa (reinterpret_cast <ACE_SignalHandler> (my_sighandler)); + + // Make sure we specify that SIGUSR1 will be masked out + // during the signal handler's execution. + ACE_Sig_Set ss; + ss.sig_add (SIGUSR1); + sa.mask (ss); + + // Register the same handler function for these + // two signals. + sa.register_action (SIGUSR1); + sa.register_action (SIGUSR2); +} +// Listing 2 diff --git a/ACE/examples/APG/Signals/SigGuard.cpp b/ACE/examples/APG/Signals/SigGuard.cpp new file mode 100644 index 00000000000..679af032904 --- /dev/null +++ b/ACE/examples/APG/Signals/SigGuard.cpp @@ -0,0 +1,43 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +// Listing 1 +class MySignalHandler : public ACE_Event_Handler + { + public: + virtual int handle_signal(int signo, + siginfo_t * = 0, ucontext_t * = 0) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal %d\n"), signo)); + return 0; + } + }; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + + MySignalHandler sighandler; + ACE_Sig_Handler sh; + sh.register_handler (SIGUSR1, &sighandler); + + ACE_Sig_Set ss; + ss.sig_add (SIGUSR1); + + ACE_Sig_Guard guard (&ss); + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Entering critical region\n"))); + ACE_OS::sleep (10); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Leaving critical region\n"))); + } + + // Do other stuff. + + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Signals/SigHandler.cpp b/ACE/examples/APG/Signals/SigHandler.cpp new file mode 100644 index 00000000000..b7068c9dea6 --- /dev/null +++ b/ACE/examples/APG/Signals/SigHandler.cpp @@ -0,0 +1,60 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +// Listing 1 code/ch11 +class MySignalHandler : public ACE_Event_Handler +{ +public: + MySignalHandler (int signum) : signum_(signum) + { } + + virtual ~MySignalHandler() + { } + + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0) + { + ACE_TRACE (ACE_TEXT ("MySignalHandler::handle_signal")); + + // Make sure the right handler was called back. + ACE_ASSERT (signum == this->signum_); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%S occured\n"), signum)); + return 0; + } + +private: + int signum_; +}; +// Listing 1 +// Listing 2 code/ch11 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + MySignalHandler h1 (SIGUSR1), h2 (SIGUSR2); + ACE_Sig_Handler handler; + handler.register_handler (SIGUSR1, &h1); + handler.register_handler (SIGUSR2, &h2); + + ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); + ACE_OS::kill (ACE_OS::getpid (), SIGUSR2); + + int time = 10; + while ((time = ACE_OS::sleep (time)) == -1) + { + if (errno == EINTR) + continue; + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("sleep")), -1); + } + } + return 0; +} +// Listing 2 diff --git a/ACE/examples/APG/Signals/SigHandlers.cpp b/ACE/examples/APG/Signals/SigHandlers.cpp new file mode 100644 index 00000000000..19634b50d72 --- /dev/null +++ b/ACE/examples/APG/Signals/SigHandlers.cpp @@ -0,0 +1,54 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +class MySignalHandler : public ACE_Event_Handler +{ +public: + MySignalHandler (int signum) : signum_(signum) + { } + + virtual ~MySignalHandler () + { } + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0) + { + ACE_TRACE (ACE_TEXT ("MySignalHandler::handle_signal")); + + // Make sure the right handler was called back.. + ACE_ASSERT(signum == this->signum_); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d occured\n"), signum)); + + return 0; + } + +private: + int signum_; +}; + +// Listing 1 code/ch11 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + MySignalHandler h1 (SIGUSR1), h2 (SIGUSR1); + ACE_Sig_Handlers handler; + handler.register_handler (SIGUSR1, &h1); + handler.register_handler (SIGUSR1, &h2); + + ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); + + int time = 10; + while ((time = ACE_OS::sleep (time)) == -1) + { + if (errno == EINTR) + continue; + else + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("sleep")), -1); + } + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Signals/SigInfo.cpp b/ACE/examples/APG/Signals/SigInfo.cpp new file mode 100644 index 00000000000..0a3186e6099 --- /dev/null +++ b/ACE/examples/APG/Signals/SigInfo.cpp @@ -0,0 +1,167 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Event_Handler.h" +#include "ace/Signal.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_string.h" + +#if !defined (ACE_LACKS_UNIX_SIGNALS) + +// Listing 1 code/ch11 +class MySignalHandler : public ACE_Event_Handler +{ +public: + MySignalHandler () : ACE_Event_Handler() + { } + + // Listing A code/ch11 + int handle_signal (int signum, + siginfo_t * siginfo = 0, + ucontext_t * = 0) + { + ACE_DEBUG ((LM_INFO, ACE_TEXT ("Received signal [%S]\n"), + signum)); + if (siginfo == 0) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("No siginfo_t available for ") + ACE_TEXT ("signal [%S]\n"), + signum)); + return 0; + } + // Listing A +#if defined (__linux__) + // Listing B code/ch11 + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("errno for this signal is %d [%s]\n"), + siginfo->si_errno, + ACE_OS::strerror (siginfo->si_errno))); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("signal was sent by process %d") + ACE_TEXT (" / user %d\n"), + siginfo->si_pid, + siginfo->si_uid)); + + switch (siginfo->si_code) + { + case SI_TIMER: + ACE_DEBUG ((LM_INFO, ACE_TEXT ("Timer expiration\n"))); + break; + + case SI_USER: + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Sent by kill, sigsend or raise\n"))); + break; + + case SI_KERNEL: + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Sent by kernel\n"))); + break; + // ... + }; + + // Listing B + + // Listing C code/ch11 + switch (signum) + { + case SIGFPE: + switch (siginfo->si_code) + { + case FPE_INTDIV: + case FPE_FLTDIV: + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Divide by zero at %@\n"), + siginfo->si_addr)); + break; + + case FPE_INTOVF: + case FPE_FLTOVF: + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Numeric overflow at %@\n"), + siginfo->si_addr)); + break; + + // ... + } + break; + + // Listing C + // Listing D code/ch11 + case SIGSEGV: + switch (siginfo->si_code) + { + // ... + }; + break; + // Listing D + + // Listing E code/ch11 + case SIGCHLD: + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("A child process has exited\n"))); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("The child consumed %l/%l time\n"), + siginfo->si_utime, + siginfo->si_stime)); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("and exited with value %d\n"), + siginfo->si_status)); + break; + // ... + } + // Listing E +#endif /* __linux__ */ + return 0; + } +}; +// Listing 1 + +#endif /* ACE_LACKS_UNIX_SIGNALS */ + +#if !defined (ACE_LACKS_UNIX_SIGNALS) + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ +#if defined (ACE_LACKS_FORK) + ACE_DEBUG ((LM_DEBUG, + "This example requires fork()\n")); +#else + // Create a child process so that we can test our + // ability to handle SIGCHLD + + // Listing 2 code/ch11 + ACE_Sig_Set signalSet; + signalSet.fill_set (); + + MySignalHandler h1; + ACE_Reactor::instance ()->register_handler (signalSet, &h1); + pid_t childPid = ACE_OS::fork (); + if (childPid == 0) // This is the parent process. + { + // Exclude B + ACE_OS::sleep (10); + return 100; + // Exclude B + } + ACE_Reactor::instance ()->run_reactor_event_loop (); + // Listing 2 + +#endif /* ACE_LACKS_FORK */ + + return 0; +} + +#else + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG ((LM_DEBUG, + "This example does not work on this platform.\n")); + return 1; +} + +#endif /* !ACE_LACKS_UNIX_SIGNALS */ diff --git a/ACE/examples/APG/Signals/signals.mpc b/ACE/examples/APG/Signals/signals.mpc new file mode 100644 index 00000000000..51947c7a06b --- /dev/null +++ b/ACE/examples/APG/Signals/signals.mpc @@ -0,0 +1,37 @@ +// -*- MPC -*- +// $Id$ + +project(SigAction) : aceexe { + exename = SigAction + Source_Files { + SigAction.cpp + } +} + +project(SigGuard) : aceexe { + exename = SigGuard + Source_Files { + SigGuard.cpp + } +} + +project(SigHandler) : aceexe { + exename = SigHandler + Source_Files { + SigHandler.cpp + } +} + +project(SigHandlers) : aceexe { + exename = SigHandlers + Source_Files { + SigHandlers.cpp + } +} + +project(SigInfo) : aceexe { + exename = SigInfo + Source_Files { + SigInfo.cpp + } +} diff --git a/ACE/examples/APG/Sockets/.cvsignore b/ACE/examples/APG/Sockets/.cvsignore new file mode 100644 index 00000000000..0b2c9d92db4 --- /dev/null +++ b/ACE/examples/APG/Sockets/.cvsignore @@ -0,0 +1,8 @@ +Basic +Basic +Basic_Robust +Basic_Robust +Iovec +Iovec +Server +Server diff --git a/ACE/examples/APG/Sockets/Basic.cpp b/ACE/examples/APG/Sockets/Basic.cpp new file mode 100644 index 00000000000..6a20e435b3c --- /dev/null +++ b/ACE/examples/APG/Sockets/Basic.cpp @@ -0,0 +1,35 @@ +// $Id$ + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 1 code/ch06 + ACE_INET_Addr srvr (50000, ACE_LOCALHOST); + // Listing 1 + + // Listing 2 code/ch06 + ACE_SOCK_Connector connector; + ACE_SOCK_Stream peer; + + if (-1 == connector.connect (peer, srvr)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("connect")), 1); + // Listing 2 + + ssize_t bc; + char buf[64]; + + // Listing 3 code/ch06 + peer.send_n ("uptime\n", 7); + bc = peer.recv (buf, sizeof(buf)); + write (1, buf, bc); + peer.close (); + // Listing 3 + + return (0); +} diff --git a/ACE/examples/APG/Sockets/Basic_Robust.cpp b/ACE/examples/APG/Sockets/Basic_Robust.cpp new file mode 100644 index 00000000000..361519a4486 --- /dev/null +++ b/ACE/examples/APG/Sockets/Basic_Robust.cpp @@ -0,0 +1,137 @@ +// $Id$ + +#include "ace/OS_NS_errno.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Time_Value.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + /* + * Here we will use the default ctor and the set() + * method to configure it. After each set() we will + * display the address as a string and then connect + * to each respective server. We can reuse the addr + * instance once connection has been established. + * + // Listing 1 code/ch06 + ACE_INET_Addr addr; + ... + addr.set ("HAStatus", ACE_LOCALHOST); + ... + addr.set ("HALog", ACE_LOCALHOST); + // Listing 1 + * + */ + + ACE_INET_Addr addr; + ACE_TCHAR peerAddress[64]; + + // Listing 2 code/ch06 + addr.set (ACE_TEXT("HAStatus"), ACE_LOCALHOST); + if (addr.addr_to_string (peerAddress, + sizeof(peerAddress), 0) == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connecting to %s\n"), + peerAddress)); + } + // Listing 2 + + // Listing 3 code/ch06 + ACE_SOCK_Stream status; + ACE_OS::last_error(0); + ACE_SOCK_Connector statusConnector (status, addr); + if (ACE_OS::last_error()) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("status")), 100); + // Listing 3 + + addr.set (ACE_TEXT("HALog"), ACE_LOCALHOST); + if (addr.addr_to_string (peerAddress, + sizeof(peerAddress), 0) == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connecting to %s\n"), + peerAddress )); + } + + // Listing 4 code/ch06 + ACE_SOCK_Connector logConnector; + ACE_Time_Value timeout (10); + ACE_SOCK_Stream log; + if (logConnector.connect (log, addr, &timeout) == -1) + { + if (ACE_OS::last_error() == ETIME) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Timeout while ") + ACE_TEXT ("connecting to log server\n"))); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("log"))); + } + return (101); + } + // Listing 4 + + /* + * We generally let the OS pick our local port number but + * if you want, you can choose that also: + // Listing 5 code/ch06 + ACE_SOCK_Connector logConnector; + ACE_INET_Addr local (4200, ACE_LOCALHOST); + if (logConnector.connect (log, addr, 0, local) == -1) + { + ... + // Listing 5 + } + */ + + char buf[64]; + + // Listing 6 code/ch06 + ACE_Time_Value sendTimeout (0, 5); + if (status.send_n ("uptime\n", 7, &sendTimeout) == -1) + { + if (ACE_OS::last_error() == ETIME) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Timeout while sending ") + ACE_TEXT ("query to status server\n"))); + } + // Listing 6 + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n"))); + } + return (102); + } + + // Listing 7 code/ch06 + ssize_t bc ; + ACE_Time_Value recvTimeout (0, 1); + if ((bc = status.recv (buf, sizeof(buf), &recvTimeout)) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv"))); + return (103); + } + + log.send_n (buf, bc); + // Listing 7 + + status.close (); + log.close (); + + return (0); +} diff --git a/ACE/examples/APG/Sockets/Iovec.cpp b/ACE/examples/APG/Sockets/Iovec.cpp new file mode 100644 index 00000000000..fb27b6d562e --- /dev/null +++ b/ACE/examples/APG/Sockets/Iovec.cpp @@ -0,0 +1,84 @@ +// $Id$ + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" + +const char *UPTIME = "uptime"; +const char *HUMIDITY = "humidity"; +const char *TEMPERATURE = "temperature"; + +void addCommand (iovec [], const char *) +{} + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_INET_Addr srvr (50000, ACE_LOCALHOST); + ACE_SOCK_Connector connector; + ACE_SOCK_Stream peer; + + ACE_ASSERT (connector.connect (peer, srvr) != -1); + + ssize_t bc; + + // Listing 1 code/ch06 + iovec send[4]; + send[0].iov_base = const_cast<char *> ("up"); + send[0].iov_len = 2; + send[1].iov_base = const_cast<char *> ("time"); + send[1].iov_len = 4; + send[2].iov_base = const_cast<char *> ("\n"); + send[2].iov_len = 1; + + peer.sendv (send, 3); + // Listing 1 + + // + // A more clever approach would use something like this: + // Where the addCommand() method allocates and populates + // the query array from a set of global commands. + // + // Listing 2 code/ch06 + iovec query[3]; + addCommand (query, UPTIME); + addCommand (query, HUMIDITY); + addCommand (query, TEMPERATURE); + peer.sendv (query, 3); + // Listing 2 + + // Listing 3 code/ch06 + iovec receive[2]; + receive[0].iov_base = new char [32]; + receive[0].iov_len = 32; + receive[1].iov_base = new char [64]; + receive[1].iov_len = 64; + + bc = peer.recvv (receive, 2); + // Listing 3 + + // Listing 4 code/ch06 + for (int i = 0; i < 2 && bc > 0; ++i) + { + size_t wc = receive[i].iov_len; + if (static_cast<size_t> (bc) < wc) + wc = static_cast<size_t> (bc); + write (1, receive[i].iov_base, wc); + bc -= receive[i].iov_len; + delete [] + (reinterpret_cast<char *> (receive[i].iov_base)); + } + // Listing 4 + + // Listing 5 code/ch06 + peer.send_n ("uptime\n", 7); + iovec response; + peer.recvv (&response); + write (1, response.iov_base, response.iov_len); + delete [] reinterpret_cast<char *> (response.iov_base); + // Listing 5 + + peer.close (); + + return (0); +} diff --git a/ACE/examples/APG/Sockets/Makefile.am b/ACE/examples/APG/Sockets/Makefile.am new file mode 100644 index 00000000000..3409703f567 --- /dev/null +++ b/ACE/examples/APG/Sockets/Makefile.am @@ -0,0 +1,72 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Sockets_Basic.am +noinst_PROGRAMS = Basic + +Basic_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Basic_SOURCES = \ + Basic.cpp + +Basic_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sockets_Basic_Robust.am +noinst_PROGRAMS += Basic_Robust + +Basic_Robust_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Basic_Robust_SOURCES = \ + Basic_Robust.cpp + +Basic_Robust_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sockets_Iovec.am +noinst_PROGRAMS += Iovec + +Iovec_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Iovec_SOURCES = \ + Iovec.cpp + +Iovec_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sockets_Server.am +noinst_PROGRAMS += Server + +Server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Server_SOURCES = \ + Server.cpp + +Server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Sockets/Server.cpp b/ACE/examples/APG/Sockets/Server.cpp new file mode 100644 index 00000000000..2a9ca7f4f7b --- /dev/null +++ b/ACE/examples/APG/Sockets/Server.cpp @@ -0,0 +1,95 @@ +// $Id$ + +#include "ace/os_include/os_netdb.h" +#include "ace/OS_NS_errno.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/Time_Value.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Listing 1 code/ch06 + ACE_INET_Addr port_to_listen ("HAStatus"); + ACE_SOCK_Acceptor acceptor; + + if (acceptor.open (port_to_listen, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("acceptor.open")), + 100); + // Listing 1 + + /* + * The complete open signature: + * + // Listing 2 code/ch06 + int open (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_INET, + int backlog = ACE_DEFAULT_BACKLOG, + int protocol = 0); + // Listing 2 + * + */ + + while (1) + { + ACE_SOCK_Stream peer; + ACE_INET_Addr peer_addr; + ACE_Time_Value timeout (10, 0); + + /* + * Basic acceptor usage + */ +#if 0 + // Listing 3 code/ch06 + if (acceptor.accept (peer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Failed to accept ") + ACE_TEXT ("client connection\n")), + 100); + // Listing 3 +#endif /* 0 */ + + // Listing 4 code/ch06 + if (acceptor.accept (peer, &peer_addr, &timeout, 0) == -1) + { + if (ACE_OS::last_error() == EINTR) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Interrupted while ") + ACE_TEXT ("waiting for connection\n"))); + else + if (ACE_OS::last_error() == ETIMEDOUT) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Timeout while ") + ACE_TEXT ("waiting for connection\n"))); + } + // Listing 4 + // Listing 5 code/ch06 + else + { + ACE_TCHAR peer_name[MAXHOSTNAMELEN]; + peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connection from %s\n"), + peer_name)); + // Listing 5 + // Listing 7 code/ch06 + char buffer[4096]; + ssize_t bytes_received; + + while ((bytes_received = + peer.recv (buffer, sizeof(buffer))) != -1) + { + peer.send_n (buffer, bytes_received); + } + + peer.close (); + // Listing 7 + } + } + + ACE_NOTREACHED (return 0); +} diff --git a/ACE/examples/APG/Sockets/sockets.mpc b/ACE/examples/APG/Sockets/sockets.mpc new file mode 100644 index 00000000000..86064233ac3 --- /dev/null +++ b/ACE/examples/APG/Sockets/sockets.mpc @@ -0,0 +1,30 @@ +// -*- MPC -*- +// $Id$ + +project(*Basic) : aceexe { + exename = Basic + Source_Files { + Basic.cpp + } +} + +project(*Basic Robust) : aceexe { + exename = Basic_Robust + Source_Files { + Basic_Robust.cpp + } +} + +project(*Iovec) : aceexe { + exename = Iovec + Source_Files { + Iovec.cpp + } +} + +project(*Server) : aceexe { + exename = Server + Source_Files { + Server.cpp + } +} diff --git a/ACE/examples/APG/Streams/.cvsignore b/ACE/examples/APG/Streams/.cvsignore new file mode 100644 index 00000000000..ff318c0de98 --- /dev/null +++ b/ACE/examples/APG/Streams/.cvsignore @@ -0,0 +1,2 @@ +Answerer +Answerer diff --git a/ACE/examples/APG/Streams/Answerer.cpp b/ACE/examples/APG/Streams/Answerer.cpp new file mode 100644 index 00000000000..507b6172108 --- /dev/null +++ b/ACE/examples/APG/Streams/Answerer.cpp @@ -0,0 +1,403 @@ +/** + * $Id$ + * + * Streams Listing 01 + * + * An answering machine based on a one-way ACE_Stream + */ + +#include "ace/OS_NS_string.h" +#include "ace/Stream.h" +#include "ace/Message_Block.h" +#include "ace/FILE_IO.h" + +#include "MessageInfo.h" +#include "Message.h" +#include "BasicTask.h" +#include "EndTask.h" +#include "Util.h" +#include "RecordingDevice.h" + +// Listing 21 code/ch18 +class AnswerIncomingCall : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("AnswerIncomingCall::process()")); + + if (message->recorder ()->answer_call () < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("AnswerIncomingCall")), + -1); + return 0; + } +}; +// Listing 21 + +// Listing 22 code/ch18 +class GetCallerId : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("GetCallerId::process()")); + + CallerId *id; + id = message->recorder ()->retrieve_callerId (); + if (!id) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("GetCallerId")), + -1); + + message->caller_id (id); + return 0; + } +}; +// Listing 22 + +// Listing 23 code/ch18 +class PlayOutgoingMessage : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("PlayOutgoingMessage::process()")); + + ACE_FILE_Addr outgoing_message = + this->get_outgoing_message (message); + + int pmrv = + message->recorder ()->play_message (outgoing_message); + if (pmrv < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("PlayOutgoingMessage")), + -1); + return 0; + } + + ACE_FILE_Addr get_outgoing_message (Message *) + { + // Exclude 23 + return ACE_FILE_Addr (ACE_TEXT ("/tmp/outgoing_message")); + // Exclude 23 + } +}; +// Listing 23 + +// Listing 24 code/ch18 +class RecordIncomingMessage : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("RecordIncomingMessage::process()")); + + ACE_FILE_Addr incoming_message = + this->get_incoming_message_queue (); + + MessageType *type = + message->recorder ()->record_message (incoming_message); + if (!type) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("RecordIncomingMessage")), + -1); + message->incoming_message (incoming_message, type); + return 0; + } + + ACE_FILE_Addr get_incoming_message_queue (void) + { + // Exclude 24 + return ACE_FILE_Addr (ACE_TEXT ("/tmp/incoming_message")); + // Exclude 24 + } +}; +// Listing 24 + +// Listing 25 code/ch18 +class ReleaseDevice : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("ReleaseDevice::process()")); + message->recorder ()->release (); + return 0; + } +}; +// Listing 25 + +// Listing 26 code/ch18 +class EncodeMessage : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("ReleaseDevice::process()")); + + ACE_FILE_Addr &incoming = message->addr (); + ACE_FILE_Addr addr = this->get_message_destination (message); + + if (message->is_text ()) + Util::convert_to_unicode (incoming, addr); + else if (message->is_audio ()) + Util::convert_to_mp3 (incoming, addr); + else if (message->is_video ()) + Util::convert_to_mpeg (incoming, addr); + + message->addr (addr); + return 0; + } + + ACE_FILE_Addr get_message_destination (Message *) + { + // Exclude 26 + return ACE_FILE_Addr (ACE_TEXT ("/tmp/encoded_message")); + // Exclude 26 + } +}; +// Listing 26 + +// Listing 27 code/ch18 +class SaveMetaData : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("SaveMetaData::process()")); + + ACE_TString path (message->addr ().get_path_name ()); + path += ACE_TEXT (".xml"); + + ACE_FILE_Connector connector; + ACE_FILE_IO file; + ACE_FILE_Addr addr (path.c_str ()); + if (connector.connect (file, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("create meta-data file")), + 0); + + file.truncate (0); + this->write (file, "<Message>\n"); + // ... + this->write (file, "</Message>\n"); + file.close (); + return 0; + } + +private: + int write (ACE_FILE_IO &file, const char *str) + { + return file.send (str, ACE_OS::strlen (str)); + } +}; +// Listing 27 + +// Listing 28 code/ch18 +class NotifySomeone : public BasicTask +{ +protected: + virtual int process (Message *message) + { + ACE_TRACE (ACE_TEXT ("NotifySomeone::process()")); + + // Format an email to tell someone about the + // newly received message. + // ... + + // Display message information in the logfile + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("New message from %s ") + ACE_TEXT ("received and stored at %s\n"), + message->caller_id ()->string (), + message->addr ().get_path_name ())); + return 0; + } +}; +// Listing 28 + +// Listing 10 code/ch18 +class RecordingStream : public ACE_Stream<ACE_MT_SYNCH> +{ +public: + typedef ACE_Stream<ACE_MT_SYNCH> inherited; + typedef ACE_Module<ACE_MT_SYNCH> Module; + + RecordingStream () : inherited() + { } +// Listing 10 + + // Listing 1000 code/ch18 + virtual int open (void *arg, + Module *head = 0, Module *tail = 0) + { + if (tail == 0) + ACE_NEW_RETURN (tail, + Module (ACE_TEXT ("End Module"), new EndTask ()), + -1); + this->inherited::open (arg, head, tail); + // Listing 1000 + + // Listing 1001 code/ch18 + Module *answerIncomingCallModule; + ACE_NEW_RETURN (answerIncomingCallModule, + Module (ACE_TEXT ("Answer Incoming Call"), + new AnswerIncomingCall ()), + -1); + + // Listing 11 code/ch18 + Module *getCallerIdModule; + ACE_NEW_RETURN (getCallerIdModule, + Module (ACE_TEXT ("Get Caller ID"), new GetCallerId ()), + -1); + // Listing 11 + + Module *playOGMModule; + ACE_NEW_RETURN (playOGMModule, + Module (ACE_TEXT ("Play Outgoing Message"), + new PlayOutgoingMessage ()), + -1); + + Module *recordModule; + ACE_NEW_RETURN (recordModule, + Module (ACE_TEXT ("Record Incoming Message"), + new RecordIncomingMessage ()), + -1); + + Module *releaseModule; + ACE_NEW_RETURN (releaseModule, + Module (ACE_TEXT ("Release Device"), + new ReleaseDevice ()), + -1); + + Module *conversionModule; + ACE_NEW_RETURN (conversionModule, + Module (ACE_TEXT ("Encode Message"), + new EncodeMessage ()), + -1); + + Module *saveMetaDataModule; + ACE_NEW_RETURN (saveMetaDataModule, + Module (ACE_TEXT ("Save Meta-Data"), + new SaveMetaData ()), + -1); + + Module *notificationModule; + ACE_NEW_RETURN (notificationModule, + Module (ACE_TEXT ("Notify Someone"), + new NotifySomeone ()), + -1); + // Listing 1001 + + // Listing 12 code/ch18 + if (this->push (notificationModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("notificationModule")), + -1); + if (this->push (saveMetaDataModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("saveMetaDataModule")), + -1); + if (this->push (conversionModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("conversionModule")), + -1); + if (this->push (releaseModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("releaseModule")), + -1); + if (this->push (recordModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("recordModule")), + -1); + if (this->push (playOGMModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("playOGMModule")), + -1); + if (this->push (getCallerIdModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + ACE_TEXT ("getCallerIdModule")), + -1); + if (this->push (answerIncomingCallModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n") + ACE_TEXT ("answerIncomingCallModule")), + -1); + // Listing 12 + + return 0; + } + + // Listing 13 code/ch18 + int record (RecordingDevice *recorder) + { + ACE_Message_Block * mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof(Message)), -1); + + Message *message = (Message *)mb->wr_ptr (); + mb->wr_ptr (sizeof(Message)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("RecordingStream::record() - ") + ACE_TEXT ("message->recorder(recorder)\n"))); + message->recorder (recorder); + + int rval = this->put (mb); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("RecordingStream::record() - ") + ACE_TEXT ("this->put() returns %d\n"), + rval)); + return rval; + } + // Listing 13 +}; + + +// Listing 1 code/ch18 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + RecordingDevice *recorder = + RecordingDeviceFactory::instantiate (argc, argv); + // Listing 1 + + // Listing 2 code/ch18 + RecordingStream *recording_stream; + ACE_NEW_RETURN (recording_stream, RecordingStream, -1); + + if (recording_stream->open (0) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("RecordingStream->open()")), + 0); + // Listing 2 + + // Listing 3 code/ch18 + for (;;) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Waiting for incoming message\n"))); + RecordingDevice *activeRecorder = + recorder->wait_for_activity (); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Initiating recording process\n"))); + + recording_stream->record (activeRecorder); + } + // Listing 3 + + return 0; +} diff --git a/ACE/examples/APG/Streams/BasicTask.h b/ACE/examples/APG/Streams/BasicTask.h new file mode 100644 index 00000000000..edebc397998 --- /dev/null +++ b/ACE/examples/APG/Streams/BasicTask.h @@ -0,0 +1,143 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef BASIC_TASK_H +#define BASIC_TASK_H + +#include "ace/Task_T.h" +#include "ace/ace_wchar.h" + +// Listing 100 code/ch18 +class BasicTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + typedef ACE_Task<ACE_MT_SYNCH> inherited; + + BasicTask () : inherited() + { } + + virtual int open (void * = 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("BasicTask::open() starting ") + ACE_TEXT ("%d threads\n"), + this->desired_threads ())); + + return this->activate (THR_NEW_LWP | THR_JOINABLE, + this->desired_threads ()); + } + // Listing 100 + + // Listing 101 code/ch18 + int put (ACE_Message_Block *message, + ACE_Time_Value *timeout) + { + return this->putq (message, timeout); + } + // Listing 101 + + // Listing 1020 code/ch18 + virtual int svc (void) + { + for (ACE_Message_Block *message = 0; ; ) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("BasicTask::svc() - ") + ACE_TEXT ("waiting for work\n" ))); + + if (this->getq (message) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("getq")), + -1); + // Listing 1020 + + // Listing 1021 code/ch18 + if (message->msg_type () == ACE_Message_Block::MB_HANGUP) + { + if (this->putq (message) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Task::svc() putq"))); + message->release (); + } + break; + } + // Listing 1021 + + // Listing 1022 code/ch18 + Message *recordedMessage = + (Message *)message->rd_ptr (); + + if (this->process (recordedMessage) == -1) + { + message->release (); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("process")), + -1); + } + // Listing 1022 + + // Listing 1023 code/ch18 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("BasicTask::svc() - ") + ACE_TEXT ("Continue to next stage\n" ))); + if (this->next_step (message) < 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("put_next failed"))); + message->release (); + break; + } + // Listing 1023 + } + + return 0; + } + + // Listing 103 code/ch18 + virtual int close (u_long flags) + { + int rval = 0; + + if (flags == 1) + { + ACE_Message_Block *hangup = new ACE_Message_Block (); + hangup->msg_type (ACE_Message_Block::MB_HANGUP); + if (this->putq (hangup) == -1) + { + hangup->release (); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Task::close() putq")), + -1); + } + + rval = this->wait (); + } + + return rval; + } + // Listing 103 + + // Listing 105 code/ch18 +protected: + virtual int next_step (ACE_Message_Block *message_block) + { + return this->put_next (message_block); + } + // Listing 105 + + // Listing 104 code/ch18 + virtual int process (Message *message) = 0; + + virtual int desired_threads (void) + { + return 1; + } +}; +// Listing 104 + +#endif /* BASIC_TASK_H */ diff --git a/ACE/examples/APG/Streams/Command.h b/ACE/examples/APG/Streams/Command.h new file mode 100644 index 00000000000..eae0f5ecb5f --- /dev/null +++ b/ACE/examples/APG/Streams/Command.h @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef COMMAND_H +#define COMMAND_H + +#include "ace/SString.h" +#include "ace/Message_Block.h" + +// Listing 01 code/ch18 +class Command : public ACE_Data_Block +{ +public: + // Result Values + enum { + RESULT_PASS = 1, + RESULT_SUCCESS = 0, + RESULT_FAILURE = -1 + }; + + // Commands + enum { + CMD_UNKNOWN = -1, + CMD_ANSWER_CALL = 10, + CMD_RETRIEVE_CALLER_ID, + CMD_PLAY_MESSAGE, + CMD_RECORD_MESSAGE + } commands; + + int flags_; + int command_; + + void *extra_data_; + + int numeric_result_; + ACE_TString result_; +}; +// Listing 01 + +#endif /* COMMAND_H */ diff --git a/ACE/examples/APG/Streams/CommandModule.cpp b/ACE/examples/APG/Streams/CommandModule.cpp new file mode 100644 index 00000000000..9ee5a92918a --- /dev/null +++ b/ACE/examples/APG/Streams/CommandModule.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "CommandModule.h" + +// Listing 01 code/ch18 +CommandModule::CommandModule (const ACE_TCHAR *module_name, + CommandTask *writer, + CommandTask *reader, + ACE_SOCK_Stream *peer) + : inherited(module_name, writer, reader, peer) +{ } +// Listing 01 + +// Listing 02 code/ch18 +ACE_SOCK_Stream &CommandModule::peer (void) +{ + ACE_SOCK_Stream *peer = (ACE_SOCK_Stream *)this->arg (); + return *peer; +} +// Listing 02 diff --git a/ACE/examples/APG/Streams/CommandModule.h b/ACE/examples/APG/Streams/CommandModule.h new file mode 100644 index 00000000000..7fe65b81f78 --- /dev/null +++ b/ACE/examples/APG/Streams/CommandModule.h @@ -0,0 +1,27 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef COMMAND_MODULE_H +#define COMMAND_MODULE_H + +#include "ace/Module.h" +#include "ace/SOCK_Stream.h" +#include "CommandTask.h" + +// Listing 01 code/ch18 +class CommandModule : public ACE_Module<ACE_MT_SYNCH> +{ +public: + typedef ACE_Module<ACE_MT_SYNCH> inherited; + typedef ACE_Task<ACE_MT_SYNCH> Task; + + CommandModule (const ACE_TCHAR *module_name, + CommandTask *writer, + CommandTask *reader, + ACE_SOCK_Stream *peer); + + ACE_SOCK_Stream &peer (void); +}; +// Listing 01 + +#endif /* COMMAND_MODULE_H */ diff --git a/ACE/examples/APG/Streams/CommandStream.cpp b/ACE/examples/APG/Streams/CommandStream.cpp new file mode 100644 index 00000000000..def3f123d77 --- /dev/null +++ b/ACE/examples/APG/Streams/CommandStream.cpp @@ -0,0 +1,97 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/OS_Memory.h" +#include "CommandStream.h" +#include "Command.h" +#include "CommandModule.h" +#include "CommandTasks.h" + +// Gotcha: superclass' open() won't open head/tail modules +// Gotcha!! Must open the stream before pushing modules! + +// Listing 01 code/ch18 +int CommandStream::open (void *arg, + ACE_Module<ACE_MT_SYNCH> *head, + ACE_Module<ACE_MT_SYNCH> *tail) +{ + ACE_TRACE (ACE_TEXT ("CommandStream::open(peer)")); + + if (this->inherited::open (arg, head, tail) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Failed to open superclass")), + -1); + // Listing 01 + + // Listing 02 code/ch18 + CommandModule *answerCallModule; + ACE_NEW_RETURN (answerCallModule, + AnswerCallModule (this->peer_), + -1); + + CommandModule *retrieveCallerIdModule; + ACE_NEW_RETURN (retrieveCallerIdModule, + RetrieveCallerIdModule (this->peer_), + -1); + + CommandModule *playMessageModule; + ACE_NEW_RETURN (playMessageModule, + PlayMessageModule (this->peer_), + -1); + + CommandModule *recordMessageModule; + ACE_NEW_RETURN (recordMessageModule, + RecordMessageModule (this->peer_), + -1); + // Listing 02 + + // Listing 03 code/ch18 + if (this->push (answerCallModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + answerCallModule->name()), + -1); + + if (this->push (retrieveCallerIdModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + retrieveCallerIdModule->name()), + -1); + + if (this->push (playMessageModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + playMessageModule->name()), + -1); + + if (this->push (recordMessageModule) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Failed to push %p\n"), + recordMessageModule->name()), + -1); + // Listing 03 + return 0; +} + +// Listing 04 code/ch18 +Command *CommandStream::execute (Command *command) +{ + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (command), 0); + if (this->put (mb) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Fail on put command %d: %p\n"), + command->command_, + ACE_TEXT ("")), + 0); + + this->get (mb); + command = (Command *)mb->data_block (); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Command (%d) returns (%d)\n"), + command->command_, + command->numeric_result_)); + + return command; +} +// Listing 04 diff --git a/ACE/examples/APG/Streams/CommandStream.h b/ACE/examples/APG/Streams/CommandStream.h new file mode 100644 index 00000000000..97e9e673f7c --- /dev/null +++ b/ACE/examples/APG/Streams/CommandStream.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef COMMAND_STREAM_H +#define COMMAND_STREAM_H + +#include "ace/Module.h" +#include "ace/Stream.h" +#include "ace/SOCK_Stream.h" +#include "ace/Synch_Traits.h" + +#include "Command.h" + +// A CommandStream is a bidirectional ACE_Stream implementing a chain +// of commands. A message will move down the stream until a +// CommandModule is capable of processing it. After processing, it +// will move on down the stream to the end. Data received from the +// tail will likewise move up the stream until the downstream's +// partner module is encoutered. The retrieved data will be processed +// and continue on up the stream. + +// Listing 01 code/ch18 +class CommandStream : public ACE_Stream<ACE_MT_SYNCH> +{ +public: + typedef ACE_Stream<ACE_MT_SYNCH> inherited; + + CommandStream (ACE_SOCK_Stream *peer) + : inherited (), peer_(peer) { } + + virtual int open (void *arg, + ACE_Module<ACE_MT_SYNCH> *head = 0, + ACE_Module<ACE_MT_SYNCH> *tail = 0); + + Command *execute (Command *command); + +private: + CommandStream () { } + + ACE_SOCK_Stream *peer_; +}; +// Listing 01 + +#endif /* COMMAND_STREAM_H */ diff --git a/ACE/examples/APG/Streams/CommandTask.cpp b/ACE/examples/APG/Streams/CommandTask.cpp new file mode 100644 index 00000000000..7ad63166ffd --- /dev/null +++ b/ACE/examples/APG/Streams/CommandTask.cpp @@ -0,0 +1,153 @@ +// $Id$ + +#include "CommandTask.h" + +// Listing 01 code/ch18 +CommandTask::CommandTask (int command) + : inherited (), command_(command) +{ } +// Listing 01 + +// Listing 02 code/ch18 +int CommandTask::open (void *) +{ + return this->activate (); +} +// Listing 02 + +// Listing 03 code/ch18 +int CommandTask::put (ACE_Message_Block *message, + ACE_Time_Value *timeout) +{ + return this->putq (message, timeout); +} +// Listing 03 + +// Listing 04 code/ch18 +int CommandTask::process (Command *) +{ + ACE_TRACE (ACE_TEXT ("CommandTask::process()")); + return Command::RESULT_FAILURE; +} +// Listing 04 + +// Listing 05 code/ch18 +int CommandTask::close (u_long flags) +{ + int rval = 0; + if (flags == 1) + { + ACE_Message_Block *hangup = new ACE_Message_Block; + hangup->msg_type (ACE_Message_Block::MB_HANGUP); + if (this->putq (hangup->duplicate ()) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Task::close() putq")), + -1); + } + + hangup->release (); + rval = this->wait (); + } + + return rval; +} +// Listing 05 + +// Listing 06 code/ch18 +// Listing 061 code/ch18 +int CommandTask::svc (void) +{ + ACE_Message_Block *message; + + for (;;) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CommandTask::svc() - ") + ACE_TEXT ("%s waiting for work\n"), + this->module ()->name ())); + + if (this->getq (message) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("getq")), + -1); + + if (message->msg_type () == ACE_Message_Block::MB_HANGUP) + { + if (this->putq (message->duplicate ()) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Task::svc() putq")), + -1); + } + + message->release (); + break; + } + // Listing 061 + + // Listing 062 code/ch18 + Command *command = (Command *)message->data_block (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CommandTask::svc() - ") + ACE_TEXT ("%s got work request %d\n"), + this->module ()->name (), + command->command_)); + + if (command->command_ != this->command_) + { + this->put_next (message->duplicate ()); + } + // Listing 062 + // Listing 063 code/ch18 + else + { + int result = this->process (command); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CommandTask::svc() - ") + ACE_TEXT ("%s work request %d result is %d\n"), + this->module ()->name (), + command->command_, + result)); + + if (result == Command::RESULT_FAILURE) + { + command->numeric_result_ = -1; + } + // Listing 063 + // Listing 064 code/ch18 + else if (result == Command::RESULT_PASS) + { + this->put_next (message->duplicate ()); + } + // Listing 064 + // Listing 065 code/ch18 + else // result == Command::RESULT_SUCCESS + { + if (this->is_writer ()) + { + this->sibling ()->putq + (message->duplicate ()); + } + // Listing 065 + // Listing 066 code/ch18 + else // this->is_reader () + { + this->put_next (message->duplicate ()); + } + // Listing 066 + } // result == ... + } // command->command_ ? = this->command_ + + // Listing 067 code/ch18 + message->release (); + } // for (;;) + + return 0; +} +// Listing 067 +// Listing 06 diff --git a/ACE/examples/APG/Streams/CommandTask.h b/ACE/examples/APG/Streams/CommandTask.h new file mode 100644 index 00000000000..ae78017b0f9 --- /dev/null +++ b/ACE/examples/APG/Streams/CommandTask.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef COMMAND_TASK_H +#define COMMAND_TASK_H + +#include "ace/Task.h" +#include "ace/Module.h" + +#include "Command.h" + +// Listing 01 code/ch18 +class CommandTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + typedef ACE_Task<ACE_MT_SYNCH> inherited; + + virtual ~CommandTask () { } + + virtual int open (void * = 0 ); + + int put (ACE_Message_Block *message, + ACE_Time_Value *timeout); + + virtual int svc (void); + + virtual int close (u_long flags); + +protected: + CommandTask (int command); + + virtual int process (Command *message); + + int command_; +}; +// Listing 01 + + +#endif /* COMMAND_TASK_H */ diff --git a/ACE/examples/APG/Streams/CommandTasks.cpp b/ACE/examples/APG/Streams/CommandTasks.cpp new file mode 100644 index 00000000000..78a5e2de451 --- /dev/null +++ b/ACE/examples/APG/Streams/CommandTasks.cpp @@ -0,0 +1,221 @@ +// $Id$ + +#include "ace/FILE_Addr.h" +#include "ace/FILE_Connector.h" +#include "ace/FILE_IO.h" + +#include "Command.h" +#include "CommandTasks.h" +#include "RecordingDevice_Text.h" + +// Listing 011 code/ch18 +AnswerCallModule::AnswerCallModule (ACE_SOCK_Stream *peer) + : CommandModule (ACE_TEXT ("AnswerCall Module"), + new AnswerCallDownstreamTask (), + new AnswerCallUpstreamTask (), + peer) +{ } +// Listing 011 +// Listing 012 code/ch18 +AnswerCallDownstreamTask::AnswerCallDownstreamTask (void) + : CommandTask(Command::CMD_ANSWER_CALL) +{ } +// Listing 012 +// Listing 013 code/ch18 +int AnswerCallDownstreamTask::process (Command *command) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Answer Call (downstream)\n"))); + + TextListenerAcceptor *acceptor = + (TextListenerAcceptor *)command->extra_data_; + + CommandModule *module = + (CommandModule*)this->module (); + + command->numeric_result_ = + acceptor->accept (module->peer ()); + + acceptor->release (); + return Command::RESULT_SUCCESS; +} +// Listing 013 +// Listing 014 code/ch18 +AnswerCallUpstreamTask::AnswerCallUpstreamTask (void) + : CommandTask(Command::CMD_ANSWER_CALL) +{ } +// Listing 014 +// Listing 015 code/ch18 +int AnswerCallUpstreamTask::process (Command *) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Answer Call (upstream)\n"))); + + return Command::RESULT_SUCCESS; +} +// Listing 015 + +// Listing 021 code/ch18 +RetrieveCallerIdModule::RetrieveCallerIdModule + (ACE_SOCK_Stream *peer) + : CommandModule (ACE_TEXT ("RetrieveCallerId Module"), + new RetrieveCallerIdDownstreamTask (), + new RetrieveCallerIdUpstreamTask (), + peer) +{ } +// Listing 021 +// Listing 022 code/ch18 +RetrieveCallerIdDownstreamTask::RetrieveCallerIdDownstreamTask + (void) + : CommandTask(Command::CMD_RETRIEVE_CALLER_ID) +{ } + +int RetrieveCallerIdDownstreamTask::process (Command *) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Retrieving Caller ID data\n"))); + + return Command::RESULT_SUCCESS; +} +// Listing 022 +// Listing 023 code/ch18 +RetrieveCallerIdUpstreamTask::RetrieveCallerIdUpstreamTask + (void) + : CommandTask(Command::CMD_RETRIEVE_CALLER_ID) +{ } + +int RetrieveCallerIdUpstreamTask::process (Command *command) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Returning Caller ID data\n"))); + + ACE_INET_Addr remote_addr; + + CommandModule *module = + (CommandModule*)this->module (); + + module->peer ().get_remote_addr (remote_addr); + ACE_TCHAR remote_addr_str[256]; + remote_addr.addr_to_string (remote_addr_str, 256); + command->result_ = ACE_TString (remote_addr_str); + + return Command::RESULT_SUCCESS; +} +// Listing 023 + +PlayMessageModule::PlayMessageModule (ACE_SOCK_Stream *peer) + : CommandModule (ACE_TEXT ("PlayMessage Module"), + new PlayMessageDownstreamTask (), + new PlayMessageUpstreamTask (), + peer) +{ } + +PlayMessageDownstreamTask::PlayMessageDownstreamTask (void) + : CommandTask(Command::CMD_PLAY_MESSAGE) +{ } +// Listing 032 code/ch18 +int PlayMessageDownstreamTask::process (Command *command) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Play Outgoing Message\n"))); + + ACE_FILE_Connector connector; + ACE_FILE_IO file; + + ACE_FILE_Addr *addr = + (ACE_FILE_Addr *)command->extra_data_; + + if (connector.connect (file, *addr) == -1) + { + command->numeric_result_ = -1; + } + else + { + command->numeric_result_ = 0; + + CommandModule *module = + (CommandModule*)this->module (); + + char rwbuf[512]; + ssize_t rwbytes; + while ((rwbytes = file.recv (rwbuf, 512)) > 0) + { + module->peer ().send_n (rwbuf, rwbytes); + } + } + + return Command::RESULT_SUCCESS; +} +// Listing 032 +PlayMessageUpstreamTask::PlayMessageUpstreamTask (void) + : CommandTask(Command::CMD_PLAY_MESSAGE) +{ } + +int PlayMessageUpstreamTask::process (Command *command) +{ + ACE_FILE_Addr * addr = + (ACE_FILE_Addr *)command->extra_data_; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Outgoing message (%s) sent\n"), + addr->get_path_name ())); + + return Command::RESULT_SUCCESS; +} + +RecordMessageModule::RecordMessageModule (ACE_SOCK_Stream *peer) + : CommandModule (ACE_TEXT ("RecordMessage Module"), + new RecordMessageDownstreamTask (), + new RecordMessageUpstreamTask (), + peer) +{ } + +RecordMessageDownstreamTask::RecordMessageDownstreamTask (void) + : CommandTask(Command::CMD_RECORD_MESSAGE) +{ } + +int RecordMessageDownstreamTask::process (Command *) +{ + return Command::RESULT_SUCCESS; +} + +RecordMessageUpstreamTask::RecordMessageUpstreamTask (void) + : CommandTask(Command::CMD_RECORD_MESSAGE) +{ } +// Listing 033 code/ch18 +int RecordMessageUpstreamTask::process (Command *command) +{ + // Collect whatever the peer sends and write into the + // specified file. + ACE_FILE_Connector connector; + ACE_FILE_IO file; + + ACE_FILE_Addr *addr = + (ACE_FILE_Addr *)command->extra_data_; + + if (connector.connect (file, *addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("create file")), + Command::RESULT_FAILURE); + file.truncate (0); + + CommandModule *module = + (CommandModule*)this->module (); + + ssize_t total_bytes = 0; + char rwbuf[512]; + ssize_t rwbytes; + while ((rwbytes = module->peer ().recv (rwbuf, 512)) > 0) + { + total_bytes += file.send_n (rwbuf, rwbytes); + } + + file.close (); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("RecordMessageUpstreamTask ") + ACE_TEXT ("- recorded %d byte message\n"), + total_bytes)); + + return Command::RESULT_SUCCESS; +} +// Listing 033 diff --git a/ACE/examples/APG/Streams/CommandTasks.h b/ACE/examples/APG/Streams/CommandTasks.h new file mode 100644 index 00000000000..0d55d4da07b --- /dev/null +++ b/ACE/examples/APG/Streams/CommandTasks.h @@ -0,0 +1,108 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef COMMAND_TASKS_H +#define COMMAND_TASKS_H + +#include "ace/SOCK_Stream.h" + +#include "Command.h" +#include "CommandTask.h" +#include "CommandModule.h" + +// CommandModule and CommandTask objects that implement the command +// stream functions. + +// Listing 011 code/ch18 +class AnswerCallModule : public CommandModule +{ +public: + AnswerCallModule (ACE_SOCK_Stream * peer); +}; +// Listing 011 +// Listing 012 code/ch18 +class AnswerCallDownstreamTask : public CommandTask +{ +public: + AnswerCallDownstreamTask (); +protected: + virtual int process (Command *command); +}; +// Listing 012 +// Listing 013 code/ch18 +class AnswerCallUpstreamTask : public CommandTask +{ +public: + AnswerCallUpstreamTask (); +protected: + virtual int process (Command *command); +}; +// Listing 013 + +// Listing 02 code/ch18 +class RetrieveCallerIdModule : public CommandModule +{ +public: + RetrieveCallerIdModule (ACE_SOCK_Stream *peer); +}; +class RetrieveCallerIdDownstreamTask : public CommandTask +{ +public: + RetrieveCallerIdDownstreamTask (); +protected: + virtual int process (Command *command); +}; +class RetrieveCallerIdUpstreamTask : public CommandTask +{ +public: + RetrieveCallerIdUpstreamTask (); +protected: + virtual int process (Command *command); +}; +// Listing 02 + +// Listing 03 code/ch18 +class PlayMessageModule : public CommandModule +{ +public: + PlayMessageModule (ACE_SOCK_Stream *peer); +}; +class PlayMessageDownstreamTask : public CommandTask +{ +public: + PlayMessageDownstreamTask (); +protected: + virtual int process (Command *command); +}; +class PlayMessageUpstreamTask : public CommandTask +{ +public: + PlayMessageUpstreamTask (); +protected: + virtual int process (Command *command); +}; +// Listing 03 + +// Listing 04 code/ch18 +class RecordMessageModule : public CommandModule +{ +public: + RecordMessageModule (ACE_SOCK_Stream *peer); +}; +class RecordMessageDownstreamTask : public CommandTask +{ +public: + RecordMessageDownstreamTask (); +protected: + virtual int process (Command *command); +}; +class RecordMessageUpstreamTask : public CommandTask +{ +public: + RecordMessageUpstreamTask (); +protected: + virtual int process (Command *command); +}; +// Listing 04 + +#endif /* COMMAND_TASKS_H */ diff --git a/ACE/examples/APG/Streams/EndTask.h b/ACE/examples/APG/Streams/EndTask.h new file mode 100644 index 00000000000..a42eca655d9 --- /dev/null +++ b/ACE/examples/APG/Streams/EndTask.h @@ -0,0 +1,27 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef END_TASK_H +#define END_TASK_H + +// Listing 1 code/ch18 +class EndTask : public BasicTask { +protected: + virtual int process (Message *) + { + ACE_TRACE (ACE_TEXT ("EndTask::process()")); + return 0; + } + + virtual int next_step (ACE_Message_Block *mb) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("EndTask::next_step() - ") + ACE_TEXT ("end of the line.\n"))); + mb->release (); + return 0; + } +}; +// Listing 1 + +#endif /* END_TASK_H */ diff --git a/ACE/examples/APG/Streams/Makefile.am b/ACE/examples/APG/Streams/Makefile.am new file mode 100644 index 00000000000..e23f2f22143 --- /dev/null +++ b/ACE/examples/APG/Streams/Makefile.am @@ -0,0 +1,52 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.Answerer.am + +if BUILD_THREADS +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS = Answerer + +Answerer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Answerer_SOURCES = \ + Answerer.cpp \ + CommandModule.cpp \ + CommandStream.cpp \ + CommandTask.cpp \ + CommandTasks.cpp \ + RecordingDeviceFactory.cpp \ + RecordingDevice_Text.cpp \ + CommandModule.h \ + CommandStream.h \ + CommandTask.h \ + CommandTasks.h \ + RecordingDeviceFactory.h \ + RecordingDevice_Text.h + +Answerer_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_THREADS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Streams/Message.h b/ACE/examples/APG/Streams/Message.h new file mode 100644 index 00000000000..29ddd30d5a1 --- /dev/null +++ b/ACE/examples/APG/Streams/Message.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef MESSAGE_H +#define MESSAGE_H + +class RecordingDevice; + +class Message +{ +public: + Message () : device_(0), type_(0), id_(0) + { } + + ~Message () + { } + + RecordingDevice *recorder (void) + { + return this->device_; + } + + void recorder (RecordingDevice *device) + { + this->device_ = device; + } + + void type (MessageType *type) + { + this->type_ = type; + } + + MessageType *type (void) + { + return this->type_; + } + + void caller_id (CallerId *id) + { + this->id_ = id; + } + + CallerId *caller_id (void) + { + return this->id_; + } + + void addr (ACE_FILE_Addr &addr) + { + this->addr_ = addr; + } + + void incoming_message (ACE_FILE_Addr &addr, MessageType *type) + { + this->addr_ = addr; + this->type_ = type; + } + + ACE_FILE_Addr &addr (void) + { + return this->addr_; + } + + int is_text (void) + { + return this->type_->is_text (); + } + + int is_audio (void) + { + return this->type_->is_audio (); + } + + int is_video (void) + { + return this->type_->is_video (); + } + +private: + RecordingDevice *device_; + MessageType *type_; + CallerId *id_; + ACE_FILE_Addr addr_; +}; + +class AudioMessage : public Message +{ }; + +class VideoMessage : public Message +{ }; + +#endif /* MESSAGE_H */ diff --git a/ACE/examples/APG/Streams/MessageInfo.h b/ACE/examples/APG/Streams/MessageInfo.h new file mode 100644 index 00000000000..0f0f1bc60dc --- /dev/null +++ b/ACE/examples/APG/Streams/MessageInfo.h @@ -0,0 +1,100 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef MESSAGE_INFO_H +#define MESSAGE_INFO_H + +#include "ace/FILE_Addr.h" +#include "ace/SString.h" + +/* Opaque class that represents a caller's ID */ +class CallerId +{ +public: + CallerId () : id_ (ACE_TEXT ("UNKNOWN")) + { } + + CallerId (ACE_TString id) : id_(id) + { } + + const ACE_TCHAR * string(void) + { + return this->id_.c_str (); + } + +private: + ACE_TString id_; +}; + +class MessageType +{ +public: + enum { + // Known video codecs + FIRST_VIDEO_CODEC = 1, + + DIVX, + // ... + LAST_VIDEO_CODEC, + + // Known audio codecs + FIRST_AUDIO_CODEC, + + MP3, + RAWPCM, + // ... + LAST_AUDIO_CODEC, + + // Known text codecs + FIRST_TEXT_CODEC, + + RAWTEXT, + XML, + + // ... + LAST_TEXT_CODEC, + + LAST_CODEC + }; + + MessageType (int codec, ACE_FILE_Addr addr) + : codec_(codec), addr_(addr) + { } + + int get_codec (void) + { + return this->codec_; + } + + ACE_FILE_Addr &get_addr (void) + { + return this->addr_; + } + + int is_video (void) + { + return + this->get_codec () > FIRST_VIDEO_CODEC && + this->get_codec () < LAST_VIDEO_CODEC; + } + + int is_audio (void) + { + return + this->get_codec () > FIRST_AUDIO_CODEC && + this->get_codec () < LAST_AUDIO_CODEC ; + } + + int is_text (void) + { + return + this->get_codec () > FIRST_TEXT_CODEC && + this->get_codec () < LAST_TEXT_CODEC ; + } + +private: + int codec_; + ACE_FILE_Addr addr_; +}; + +# endif /* MESSAGE_INFO_H */ diff --git a/ACE/examples/APG/Streams/RecordingDevice.h b/ACE/examples/APG/Streams/RecordingDevice.h new file mode 100644 index 00000000000..cee3d7154de --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDevice.h @@ -0,0 +1,119 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef RECORDING_DEVICE_H +#define RECORDING_DEVICE_H + +#include "ace/FILE_Addr.h" +#include "ace/Event_Handler.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" +#include "ace/Semaphore.h" + +class CallerId; +class MessageType; + +class RecordingDevice +{ +public: + RecordingDevice () + { + // Initialize the semaphore so that we don't block on the + // first call to wait_for_activity(). + } + + virtual ~RecordingDevice () + { + } + + virtual const ACE_TCHAR *get_name (void) const + { + return ACE_TEXT ("UNKNOWN"); + } + + virtual int init (int, ACE_TCHAR *[]) + { + return 0; + } + + // Answer the incoming call + virtual int answer_call (void) = 0; + + // Fetch some form of caller identification at the hardware level. + virtual CallerId *retrieve_callerId (void) = 0; + + // Fetch the message at the location specified by 'addr' and play + // it for the caller. + virtual int play_message (ACE_FILE_Addr &addr) = 0; + + // Record data from our physical device into the file at the + // specified address. Return the number of bytes recorded. + virtual MessageType *record_message (ACE_FILE_Addr &addr) = 0; + + // Release the RecordingDevice to accept another incoming call + virtual void release (void) + { + this->release_semaphore (); + } + + // Get the handler of the device so that wait_for_activity() can + // wait for data to arrive. + virtual ACE_Event_Handler *get_handler (void) const + { + return 0; + } + + virtual RecordingDevice *wait_for_activity (void) + { + // Block on a semaphore until it says we're ready to do + // work. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Waiting for semaphore\n"))); + this->acquire_semaphore (); + + // Use the reactor to wait for activity on our handle + ACE_Reactor reactor; + + ACE_Event_Handler *handler = this->get_handler (); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler is %@\n"), + (void *)handler)); + + reactor.register_handler (this->get_handler (), + ACE_Event_Handler::READ_MASK); + + reactor.handle_events (); + // Error-check this... + + // Leave the semaphore locked so that we'll block until + // recording_complete() is invoked. + + return this; + } + +protected: + void acquire_semaphore (void) + { + this->semaphore_.acquire (); + } + + void release_semaphore (void) + { + // Reset the semaphore so that wait_for_activity() will + // unblock. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Releasing semaphore\n"))); + this->semaphore_.release (); + } + +private: + ACE_Semaphore semaphore_; +}; + +#include "RecordingDevice_Text.h" +#include "RecordingDevice_USRVM.h" +#include "RecordingDevice_QC.h" + +#include "RecordingDeviceFactory.h" + +#endif /* RECORDING_DEVICE_H */ diff --git a/ACE/examples/APG/Streams/RecordingDeviceFactory.cpp b/ACE/examples/APG/Streams/RecordingDeviceFactory.cpp new file mode 100644 index 00000000000..f5585e1ec0a --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDeviceFactory.cpp @@ -0,0 +1,25 @@ +// $Id$ + +#include "RecordingDevice.h" +#include "RecordingDeviceFactory.h" +#include "RecordingDevice_Text.h" + +RecordingDevice *RecordingDeviceFactory::instantiate (int argc, + ACE_TCHAR *argv[]) +{ + RecordingDevice * device = 0; + + // Determine the implementation based on the values of argv + // Exclude 2 + device = new TextListenerAcceptor (); + // Exclude 2 + + // Initialize the device with the remaining parameters. + if (device->init (argc, argv) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("RecordingDeviceFactory::instantiate() - ") + ACE_TEXT ("%s->init(argc, argv)"), + device->get_name()), + 0); + return device; +} diff --git a/ACE/examples/APG/Streams/RecordingDeviceFactory.h b/ACE/examples/APG/Streams/RecordingDeviceFactory.h new file mode 100644 index 00000000000..13485b20947 --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDeviceFactory.h @@ -0,0 +1,22 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef RECORDING_DEVICE_FACTORY_H +#define RECORDING_DEVICE_FACTORY_H + +class RecordingDevice; + +/* + * A factory class that creates an appropriate RecordingDevice + * derivative based on command-line parameters. + */ +class RecordingDeviceFactory +{ +public: + + // Instantiate the appropriate RecordingDevice implementation + static RecordingDevice *instantiate (int argc, ACE_TCHAR *argv[]); +}; + +#endif /* RECORDING_DEVICE_FACTORY_H */ + diff --git a/ACE/examples/APG/Streams/RecordingDevice_QC.h b/ACE/examples/APG/Streams/RecordingDevice_QC.h new file mode 100644 index 00000000000..356d70afc5c --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDevice_QC.h @@ -0,0 +1,5 @@ +// $Id$ + +class QuickCam : public RecordingDevice + { + }; diff --git a/ACE/examples/APG/Streams/RecordingDevice_Text.cpp b/ACE/examples/APG/Streams/RecordingDevice_Text.cpp new file mode 100644 index 00000000000..01720bb2470 --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDevice_Text.cpp @@ -0,0 +1,197 @@ +/* + * $Id$ + * + * A RecordingDevice that listens to a socket and collects text. + */ + +#include "MessageInfo.h" +#include "RecordingDevice.h" +#include "RecordingDevice_Text.h" +#include "Util.h" + +TextListenerAcceptor::TextListenerAcceptor (void) + : ACE_Event_Handler(), RecordingDevice() +{ } + +// ACE_Event_Handler interface + +int TextListenerAcceptor::open (ACE_INET_Addr &addr) +{ + if (this->acceptor_.open (addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("acceptor open")), + -1); + return 0; +} + +ACE_HANDLE TextListenerAcceptor::get_handle (void) const +{ + return this->acceptor_.get_handle (); +} + +int TextListenerAcceptor::handle_input (ACE_HANDLE) +{ + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("TextListenerAcceptor - connection request\n" ))); + return 0; +} + +int TextListenerAcceptor::accept (ACE_SOCK_Stream &peer) +{ + return this->acceptor_.accept (peer); +} + +// RecordingDevice interface + +// Open a listening socket on the port specified by argv. +int TextListenerAcceptor::init (int argc, ACE_TCHAR *argv[]) +{ + ACE_UNUSED_ARG(argc); + + ACE_INET_Addr addr (argv[1]); + + if (this->open (addr) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("TextListener - open")), + -1); + return 0; +} + +ACE_Event_Handler *TextListenerAcceptor::get_handler (void) const +{ + return (ACE_Event_Handler *)this; +} + +RecordingDevice *TextListenerAcceptor::wait_for_activity (void) +{ + this->RecordingDevice::wait_for_activity (); + return new TextListener (this); +} + +int TextListenerAcceptor::answer_call (void) +{ + return -1; +} + +CallerId *TextListenerAcceptor::retrieve_callerId (void) +{ + return 0; +} + +int TextListenerAcceptor::play_message (ACE_FILE_Addr &addr) +{ + ACE_UNUSED_ARG(addr); + return 0; +} + +MessageType *TextListenerAcceptor::record_message (ACE_FILE_Addr &addr) +{ + ACE_UNUSED_ARG(addr); + return 0; +} + + +// Listing 01 code/ch18 +TextListener::TextListener (TextListenerAcceptor *acceptor) + : acceptor_(acceptor) +{ + ACE_TRACE ("TextListener ctor"); + + ACE_NEW (this->command_stream_, CommandStream (&(this->peer_))); + this->command_stream_->open (0); +} +// Listing 01 + +const ACE_TCHAR *TextListener::get_name (void) const +{ + return ACE_TEXT ("TextListener"); +} + +// Listing 02 code/ch18 +int TextListener::answer_call (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TextListener::answer_call()\n"))); + + Command *c = new Command (); + c->command_ = Command::CMD_ANSWER_CALL; + c->extra_data_ = this->acceptor_; + + c = this->command_stream_->execute (c); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TextListener::answer_call() ") + ACE_TEXT ("result is %d\n"), + c->numeric_result_)); + + return c->numeric_result_; +} +// Listing 02 + +// Listing 03 code/ch18 +CallerId *TextListener::retrieve_callerId (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TextListener::retrieve_callerId()\n"))); + + Command *c = new Command (); + c->command_ = Command::CMD_RETRIEVE_CALLER_ID; + + c = this->command_stream_->execute (c); + + CallerId *caller_id = new CallerId (c->result_); + return caller_id; +} +// Listing 03 + +// Listing 04 code/ch18 +int TextListener::play_message (ACE_FILE_Addr &addr) +{ + MessageType *type = Util::identify_message (addr); + if (type->is_text ()) + { + Command *c = new Command (); + c->command_ = Command::CMD_PLAY_MESSAGE; + c->extra_data_ = &addr; + c = this->command_stream_->execute (c); + return c->numeric_result_; + } + + ACE_FILE_Addr temp (ACE_TEXT ("/tmp/outgoing_message.text")); + ACE_FILE_IO *file; + if (type->is_audio ()) + file = Util::audio_to_text (addr, temp); + else if (type->is_video ()) + file = Util::video_to_text (addr, temp); + else + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Invalid message type %d\n"), + type->get_codec ()), -1); + int rval = this->play_message (temp); + file->remove (); + return rval; +} +// Listing 04 + +// Listing 05 code/ch18 +MessageType *TextListener::record_message (ACE_FILE_Addr &addr) +{ + Command *c = new Command (); + c->command_ = Command::CMD_RECORD_MESSAGE; + c->extra_data_ = &addr; + c = this->command_stream_->execute (c); + if (c->numeric_result_ == -1) + return 0; + + return new MessageType (MessageType::RAWTEXT, addr); +} +// Listing 05 + +// Listing 06 code/ch18 +void TextListener::release (void) +{ + delete this; +} +// Listing 06 diff --git a/ACE/examples/APG/Streams/RecordingDevice_Text.h b/ACE/examples/APG/Streams/RecordingDevice_Text.h new file mode 100644 index 00000000000..a49f400d922 --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDevice_Text.h @@ -0,0 +1,84 @@ +/* -*- C++ -*- */ +/* + * $Id$ + * + * A RecordingDevice that listens to a socket and collects text. + */ + +#ifndef RECORDING_DEVICE_TEXT_H +#define RECORDING_DEVICE_TEXT_H + +#include "ace/FILE_IO.h" +#include "ace/FILE_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" + +#include "CommandStream.h" +#include "MessageInfo.h" +#include "RecordingDevice.h" + +class TextListenerAcceptor : + public ACE_Event_Handler, + public RecordingDevice +{ +public: + TextListenerAcceptor (); + + // ACE_Event_Handler interface + + int open (ACE_INET_Addr &addr); + + ACE_HANDLE get_handle (void) const; + + int handle_input (ACE_HANDLE); + + int accept (ACE_SOCK_Stream &peer); + + // RecordingDevice interface + + // Open a listening socket on the port specified by argv. + int init (int argc, ACE_TCHAR *argv[]); + + ACE_Event_Handler *get_handler (void) const; + + virtual RecordingDevice *wait_for_activity (void); + + virtual int answer_call (void); + + virtual CallerId *retrieve_callerId (void); + + virtual int play_message (ACE_FILE_Addr &addr); + + virtual MessageType *record_message (ACE_FILE_Addr &addr); + +private: + ACE_SOCK_Acceptor acceptor_; +}; + +// Listing 01 code/ch18 +class TextListener : public RecordingDevice +{ +public: + TextListener (TextListenerAcceptor *acceptor); + + virtual const ACE_TCHAR *get_name (void) const; + + int answer_call (void); + + CallerId *retrieve_callerId (void); + + int play_message (ACE_FILE_Addr &addr); + + MessageType *record_message (ACE_FILE_Addr &addr); + + virtual void release (void); + // Listing 01 + // Listing 02 code/ch18 +private: + CommandStream *command_stream_; + TextListenerAcceptor *acceptor_; + ACE_SOCK_Stream peer_; +}; +// Listing 02 + +#endif /* RECORDING_DEVICE_TEXT_H */ diff --git a/ACE/examples/APG/Streams/RecordingDevice_USRVM.h b/ACE/examples/APG/Streams/RecordingDevice_USRVM.h new file mode 100644 index 00000000000..7519f7c1c84 --- /dev/null +++ b/ACE/examples/APG/Streams/RecordingDevice_USRVM.h @@ -0,0 +1,5 @@ +// $Id$ + +class USRoboticsVoiceModem : public RecordingDevice + { + }; diff --git a/ACE/examples/APG/Streams/Util.h b/ACE/examples/APG/Streams/Util.h new file mode 100644 index 00000000000..d47a699aee7 --- /dev/null +++ b/ACE/examples/APG/Streams/Util.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef UTIL_H +#define UTIL_H + +#include "ace/FILE_Addr.h" +#include "ace/FILE_Connector.h" +#include "ace/FILE_IO.h" + +class Util +{ +public: + static MessageType *identify_message (ACE_FILE_Addr &src) + { + // Determine the contents of the specified file + return new MessageType (MessageType::RAWTEXT, src); + } + + static ACE_FILE_IO *audio_to_text (ACE_FILE_Addr &, ACE_FILE_Addr &dest) + { + ACE_FILE_Connector connector; + ACE_FILE_IO *file = 0; + if (connector.connect (*file, dest) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("create file")), + 0); + + // Convert audio data to printable text + + return file; + } + + static ACE_FILE_IO *video_to_text (ACE_FILE_Addr &, ACE_FILE_Addr &dest) + { + ACE_FILE_Connector connector; + ACE_FILE_IO *file = 0; + if (connector.connect (*file, dest) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("create file")), + 0); + + // Extract audio data from video file and convert to printable text + return file; + } + + static int convert_to_unicode (ACE_FILE_Addr &src, ACE_FILE_Addr &dest) + { + ACE_FILE_Connector connector; + ACE_FILE_IO input; + if (connector.connect (input, src) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("read file")), + 0); + ACE_FILE_IO output; + if (connector.connect (output, dest) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("create file")), + 0); + + char rwbuf[512]; + ssize_t rwbytes; + while ((rwbytes = input.recv (rwbuf, 512)) > 0) + { + output.send_n (rwbuf, rwbytes); + } + + input.close (); + output.close (); + + // Convert arbirary text to unicode + return 0; + } + + static int convert_to_mp3 (ACE_FILE_Addr &, ACE_FILE_Addr &) + { + // Convert arbitrary audio data to some standard mp3 format + return 0; + } + + static int convert_to_mpeg (ACE_FILE_Addr &, ACE_FILE_Addr &) + { + // Convert arbitrary vidio data to some standard mpeg format + return 0; + } +}; + +#endif /* UTIL_H */ diff --git a/ACE/examples/APG/Streams/streams.mpc b/ACE/examples/APG/Streams/streams.mpc new file mode 100644 index 00000000000..df74b446031 --- /dev/null +++ b/ACE/examples/APG/Streams/streams.mpc @@ -0,0 +1,17 @@ +// -*- MPC -*- +// $Id$ + +project(Answerer) : aceexe { + avoids += ace_for_tao + exename = Answerer + requires += threads + Source_Files { + Answerer.cpp + CommandModule.cpp + CommandStream.cpp + CommandTask.cpp + CommandTasks.cpp + RecordingDeviceFactory.cpp + RecordingDevice_Text.cpp + } +} diff --git a/ACE/examples/APG/Svc_Config/.cvsignore b/ACE/examples/APG/Svc_Config/.cvsignore new file mode 100644 index 00000000000..c508d301216 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/.cvsignore @@ -0,0 +1,4 @@ +HA_Configurable_Server_Dynamic +HA_Configurable_Server_Dynamic +HA_Configurable_Server_Static +HA_Configurable_Server_Static diff --git a/ACE/examples/APG/Svc_Config/HASTATUS_export.h b/ACE/examples/APG/Svc_Config/HASTATUS_export.h new file mode 100644 index 00000000000..9115c514089 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HASTATUS_export.h @@ -0,0 +1,53 @@ +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl HASTATUS +// ------------------------------ +#ifndef HASTATUS_EXPORT_H +#define HASTATUS_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (HASTATUS_HAS_DLL) +# define HASTATUS_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ! HASTATUS_HAS_DLL */ + +#if !defined (HASTATUS_HAS_DLL) +# define HASTATUS_HAS_DLL 1 +#endif /* ! HASTATUS_HAS_DLL */ + +#if defined (HASTATUS_HAS_DLL) && (HASTATUS_HAS_DLL == 1) +# if defined (HASTATUS_BUILD_DLL) +# define HASTATUS_Export ACE_Proper_Export_Flag +# define HASTATUS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* HASTATUS_BUILD_DLL */ +# define HASTATUS_Export ACE_Proper_Import_Flag +# define HASTATUS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* HASTATUS_BUILD_DLL */ +#else /* HASTATUS_HAS_DLL == 1 */ +# define HASTATUS_Export +# define HASTATUS_SINGLETON_DECLARATION(T) +# define HASTATUS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* HASTATUS_HAS_DLL == 1 */ + +// Set HASTATUS_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (HASTATUS_NTRACE) +# if (ACE_NTRACE == 1) +# define HASTATUS_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define HASTATUS_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !HASTATUS_NTRACE */ + +#if (HASTATUS_NTRACE == 1) +# define HASTATUS_TRACE(X) +#else /* (HASTATUS_NTRACE == 1) */ +# define HASTATUS_TRACE(X) ACE_TRACE _IMPL(X) +#endif /* (HASTATUS_NTRACE == 1) */ + +#endif /* HASTATUS_EXPORT_H */ + +// End of auto generated file. diff --git a/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp b/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp new file mode 100644 index 00000000000..1126a0393d1 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp @@ -0,0 +1,17 @@ +// $Id$ + +// Listing 1 code/ch19 +#include "ace/OS_main.h" +#include "ace/Service_Config.h" +#include "ace/Reactor.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_Service_Config::open (argc, argv); + + // We use this version of the event loop so that reconfigurations + // are triggered properly. + ACE_Reactor::instance ()->run_reactor_event_loop (ACE_Reactor::check_reconfiguration); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp b/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp new file mode 100644 index 00000000000..8ac10b08ee1 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp @@ -0,0 +1,18 @@ +// $Id$ + +// Listing 1 code/ch19 +#include "ace/OS_main.h" +#include "ace/Service_Config.h" +#include "ace/Reactor.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_STATIC_SVC_REGISTER (HA_Status_Descriptor); + ACE_Service_Config::open (argc, + argv, + ACE_DEFAULT_LOGGER_KEY, + 0); + ACE_Reactor::instance ()->run_reactor_event_loop (); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.cpp b/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.cpp new file mode 100644 index 00000000000..39f871a8bb3 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.cpp @@ -0,0 +1,113 @@ +/** + * $Id$ + * + * Home Automation Status server. Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/Configuration.h" +#include "ace/Configuration_Import_Export.h" +#include "ace/Get_Opt.h" +#include "HA_Status_Dynamic.h" + +// Listing 1 code/ch19 +int +HA_Status::init (int argc, ACE_TCHAR *argv[]) +{ + static const ACE_TCHAR options[] = ACE_TEXT (":f:"); + ACE_Get_Opt cmd_opts (argc, argv, options, 0); + if (cmd_opts.long_option + (ACE_TEXT ("config"), 'f', ACE_Get_Opt::ARG_REQUIRED) == -1) + return -1; + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_OS::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + while ((option = cmd_opts ()) != EOF) + switch (option) + { + case 'f': + ACE_OS::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + case ':': + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), + -1); + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Parse error.\n")), + -1); + } + + ACE_Configuration_Heap config; + config.open (); + ACE_Registry_ImpExp config_importer (config); + if (config_importer.import_config (config_file) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + config_file), + -1); + + ACE_Configuration_Section_Key status_section; + if (config.open_section (config.root_section (), + ACE_TEXT ("HAStatus"), + 0, + status_section) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Can't open HAStatus section")), + -1); + + u_int status_port; + if (config.get_integer_value (status_section, + ACE_TEXT ("ListenPort"), + status_port) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("HAStatus ListenPort ") + ACE_TEXT ("does not exist\n")), + -1); + this->listen_addr_.set (static_cast<u_short> (status_port)); + + if (this->acceptor_.open (this->listen_addr_) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("HAStatus %p\n"), + ACE_TEXT ("accept")), + -1); + + return 0; +} +// Listing 1 + +// Listing 2 code/ch19 +int +HA_Status::fini (void) +{ + this->acceptor_.close (); + return 0; +} +// Listing 2 + +// Listing 3 code/ch19 +int +HA_Status::info (ACE_TCHAR **str, size_t len) const + { + ACE_TCHAR buf[BUFSIZ]; + ACE_OS::sprintf (buf, + ACE_TEXT ("HAStatus listening on port %hu\n"), + this->listen_addr_.get_port_number ()); + if (*str == 0) + *str = ACE::strnew (buf); + else + ACE_OS::strncpy (*str, buf, len); + return static_cast<int> (ACE_OS::strlen (*str)); + } +// Listing 3 + +// Listing 4 code/ch19 +ACE_FACTORY_DEFINE (HASTATUS, HA_Status) +// Listing 4 + diff --git a/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.h b/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.h new file mode 100644 index 00000000000..c11f9a56d35 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Status_Dynamic.h @@ -0,0 +1,43 @@ +/** + * $Id$ + * + * Home Automation Status server. Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __HASTATUS_H_ +#define __HASTATUS_H_ + +// Listing 1 code/ch19 +#include "ace/OS.h" +#include "ace/Acceptor.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Service_Object.h" +#include "ace/Svc_Handler.h" + +#include "HASTATUS_export.h" + +class ClientHandler : + public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ + // ... Same as previous examples. +}; + +class HASTATUS_Export HA_Status : public ACE_Service_Object +{ + public: + virtual int init (int argc, ACE_TCHAR *argv[]); + + virtual int fini (void); + + virtual int info (ACE_TCHAR **str, size_t len) const; + + private: + ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR> acceptor_; + ACE_INET_Addr listen_addr_; +}; +// Listing 1 + +#endif /* __HASTATUS_H_ */ diff --git a/ACE/examples/APG/Svc_Config/HA_Status_Static.cpp b/ACE/examples/APG/Svc_Config/HA_Status_Static.cpp new file mode 100644 index 00000000000..ef09bcaa5cd --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Status_Static.cpp @@ -0,0 +1,121 @@ +/** + * $Id$ + * + * Home Automation Status server. Sample code from The ACE Programmer's Guide, + * Copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/Configuration.h" +#include "ace/Configuration_Import_Export.h" +#include "ace/Get_Opt.h" +#include "HA_Status_Static.h" + +// Listing 1 code/ch19 +int +HA_Status::init (int argc, ACE_TCHAR *argv[]) +{ + static const ACE_TCHAR options[] = ACE_TEXT (":f:"); + ACE_Get_Opt cmd_opts (argc, argv, options, 0); + if (cmd_opts.long_option + (ACE_TEXT ("config"), 'f', ACE_Get_Opt::ARG_REQUIRED) == -1) + return -1; + int option; + ACE_TCHAR config_file[MAXPATHLEN]; + ACE_OS::strcpy (config_file, ACE_TEXT ("HAStatus.conf")); + while ((option = cmd_opts ()) != EOF) + switch (option) + { + case 'f': + ACE_OS::strncpy (config_file, + cmd_opts.opt_arg (), + MAXPATHLEN); + break; + case ':': + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("-%c requires an argument\n"), + cmd_opts.opt_opt ()), + -1); + default: + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Parse error.\n")), -1); + } + + ACE_Configuration_Heap config; + config.open (); + ACE_Registry_ImpExp config_importer (config); + if (config_importer.import_config (config_file) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + config_file), + -1); + + ACE_Configuration_Section_Key status_section; + if (config.open_section (config.root_section (), + ACE_TEXT ("HAStatus"), + 0, + status_section) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Can't open HAStatus section")), + -1); + + u_int status_port; + if (config.get_integer_value (status_section, + ACE_TEXT ("ListenPort"), + status_port) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("HAStatus ListenPort does ") + ACE_TEXT ("not exist\n")), + -1); + this->listen_addr_.set (static_cast<u_short> (status_port)); + + if (this->acceptor_.open (this->listen_addr_) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("HAStatus %p\n"), + ACE_TEXT ("accept")), + -1); + + return 0; +} +// Listing 1 + +// Listing 2 code/ch19 +int +HA_Status::fini (void) +{ + this->acceptor_.close (); + return 0; +} +// Listing 2 + +// Listing 3 code/ch19 +int +HA_Status::info (ACE_TCHAR **str, size_t len) const + { + ACE_TCHAR buf[BUFSIZ]; + ACE_OS::sprintf (buf, ACE_TEXT ("HAStatus listening on port %hu\n"), + this->listen_addr_.get_port_number ()); + if (*str == 0) + *str = ACE::strnew (buf); + else + ACE_OS::strncpy (*str, buf, len); + return static_cast<int> (ACE_OS::strlen (*str)); + } +// Listing 3 + +// Listing 4 code/ch19 +ACE_FACTORY_DEFINE (ACE_Local_Service, HA_Status) + +ACE_STATIC_SVC_DEFINE (HA_Status_Descriptor, + ACE_TEXT ("HA_Status_Static_Service"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (HA_Status), + ACE_Service_Type::DELETE_THIS | + ACE_Service_Type::DELETE_OBJ, + 0) // Service not initially active + +ACE_STATIC_SVC_REQUIRE (HA_Status_Descriptor) +// Listing 4 + diff --git a/ACE/examples/APG/Svc_Config/HA_Status_Static.h b/ACE/examples/APG/Svc_Config/HA_Status_Static.h new file mode 100644 index 00000000000..d4926ff0460 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/HA_Status_Static.h @@ -0,0 +1,40 @@ +/** + * $Id$ + * + * Home Automation Status server. Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __HASTATUS_H_ +#define __HASTATUS_H_ + +// Listing 1 code/ch19 +#include "ace/OS.h" +#include "ace/Acceptor.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Service_Object.h" +#include "ace/Svc_Handler.h" +#include "ace/Service_Config.h" + +class ClientHandler : + public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ + // ... Same as previous examples. +}; + +class HA_Status : public ACE_Service_Object +{ + public: + virtual int init (int argc, ACE_TCHAR *argv[]); + virtual int fini (void); + virtual int info (ACE_TCHAR **str, size_t len) const; + + private: + ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR> acceptor_; + ACE_INET_Addr listen_addr_; +}; +// Listing 1 + +#endif /* __HASTATUS_H_ */ diff --git a/ACE/examples/APG/Svc_Config/Makefile.am b/ACE/examples/APG/Svc_Config/Makefile.am new file mode 100644 index 00000000000..9fa3e2f18b6 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/Makefile.am @@ -0,0 +1,80 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.HA_Configurable_Server_Dynamic.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += HA_Configurable_Server_Dynamic + +HA_Configurable_Server_Dynamic_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HA_Configurable_Server_Dynamic_SOURCES = \ + HA_Configurable_Server_Dynamic.cpp \ + HASTATUS_export.h \ + HA_Status_Dynamic.h \ + HA_Status_Static.h + +HA_Configurable_Server_Dynamic_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.HA_Configurable_Server_Static.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += HA_Configurable_Server_Static + +HA_Configurable_Server_Static_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +HA_Configurable_Server_Static_SOURCES = \ + HA_Configurable_Server_Static.cpp \ + HA_Status_Static.cpp \ + HA_Status_Static.h + +HA_Configurable_Server_Static_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Svc_Config_HA_Status.am + +if !BUILD_ACE_FOR_TAO + +noinst_LTLIBRARIES = libHA_Status.la + +libHA_Status_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DHASTATUS_BUILD_DLL + +libHA_Status_la_SOURCES = \ + HA_Status_Dynamic.cpp + +noinst_HEADERS = \ + HA_Status_Dynamic.h + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Svc_Config/status.ini b/ACE/examples/APG/Svc_Config/status.ini new file mode 100644 index 00000000000..8a36fb124fa --- /dev/null +++ b/ACE/examples/APG/Svc_Config/status.ini @@ -0,0 +1,2 @@ +[HAStatus] +"ListenPort"=dword:000001ec diff --git a/ACE/examples/APG/Svc_Config/svc.conf.dynamic b/ACE/examples/APG/Svc_Config/svc.conf.dynamic new file mode 100644 index 00000000000..e8ffb12c8ad --- /dev/null +++ b/ACE/examples/APG/Svc_Config/svc.conf.dynamic @@ -0,0 +1,2 @@ +dynamic HA_Status_Dynamic_Service Service_Object * +HA_Status:_make_HA_Status() "-f status.ini" diff --git a/ACE/examples/APG/Svc_Config/svc.conf.static b/ACE/examples/APG/Svc_Config/svc.conf.static new file mode 100644 index 00000000000..0103380c776 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/svc.conf.static @@ -0,0 +1 @@ +static HA_Status_Static_Service "-f status.ini" diff --git a/ACE/examples/APG/Svc_Config/svc_config.mpc b/ACE/examples/APG/Svc_Config/svc_config.mpc new file mode 100644 index 00000000000..ddc33b97c53 --- /dev/null +++ b/ACE/examples/APG/Svc_Config/svc_config.mpc @@ -0,0 +1,28 @@ +// -*- MPC -*- +// $Id$ + +project(*HA Status) : acelib { + avoids += ace_for_tao + sharedname = HA_Status + dynamicflags = HASTATUS_BUILD_DLL + Source_Files { + HA_Status_Dynamic.cpp + } +} + +project(HA Configurable Server Dynamic) : aceexe { + avoids += ace_for_tao + exename = HA_Configurable_Server_Dynamic + Source_Files { + HA_Configurable_Server_Dynamic.cpp + } +} + +project(HA Configurable Server Static) : aceexe { + avoids += ace_for_tao + exename = HA_Configurable_Server_Static + Source_Files { + HA_Configurable_Server_Static.cpp + HA_Status_Static.cpp + } +} diff --git a/ACE/examples/APG/ThreadManagement/.cvsignore b/ACE/examples/APG/ThreadManagement/.cvsignore new file mode 100644 index 00000000000..535a0039a50 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/.cvsignore @@ -0,0 +1,18 @@ +Async_Cancel +Async_Cancel +Coop_Cancel +Coop_Cancel +ExitHandler +ExitHandler +Pool +Pool +Priorities +Priorities +Signals +Signals +Signals2 +Signals2 +Start_Hook +Start_Hook +State +State diff --git a/ACE/examples/APG/ThreadManagement/Async_Cancel.cpp b/ACE/examples/APG/ThreadManagement/Async_Cancel.cpp new file mode 100644 index 00000000000..5d5d5fcf0e8 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Async_Cancel.cpp @@ -0,0 +1,63 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_PTHREADS) +// Only works on Pthreads... + +// Listing 1 code/ch13 +class CanceledTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Starting thread\n"))); + + if (this->set_cancel_mode () < 0) + return -1; + + while (1) + { + // Put this thread in a compute loop.. no + // cancellation points are available. + } + } + + int set_cancel_mode (void) + { + cancel_state new_state; + + // Set the cancel state to asynchronous and enabled. + new_state.cancelstate = PTHREAD_CANCEL_ENABLE; + new_state.canceltype = PTHREAD_CANCEL_ASYNCHRONOUS; + if (ACE_Thread::setcancelstate (new_state, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("cancelstate")), -1); + return 0; + } +}; +// Listing 1 +// Listing 2 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + CanceledTask task; + task.activate (); + ACE_OS::sleep (1); + ACE_Thread_Manager::instance ()->cancel_task (&task, 1); + task.wait (); + + return 0; +} +// Listing 2 + +#else /* ACE_HAS_PTHREADS */ +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + puts ("This example works on Pthreads platforms.\n"); + return 0; +} +#endif /* ACE_HAS_PTHREADS */ + diff --git a/ACE/examples/APG/ThreadManagement/Coop_Cancel.cpp b/ACE/examples/APG/ThreadManagement/Coop_Cancel.cpp new file mode 100644 index 00000000000..4a7714cf14b --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Coop_Cancel.cpp @@ -0,0 +1,68 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch13 +class CanceledTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting up \n"))); + + // Cache our ACE_Thread_Manager pointer. + ACE_Thread_Manager *mgr = this->thr_mgr (); + while (1) + { + if (mgr->testcancel (mgr->thr_self ())) + return 0; + + ACE_Message_Block *mb = 0; + ACE_Time_Value tv (0, 1000); + tv += ACE_OS::time (0); + int result = this->getq (mb, &tv); + if (result == -1 && errno == EWOULDBLOCK) + continue; + else + { + // Do real work. + } + } + + ACE_NOTREACHED (return 0); + } +}; +// Listing 1 + +// Listing 2 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + CanceledTask task; + task.activate (); + + ACE_OS::sleep (1); + + ACE_Thread_Manager::instance ()->cancel_task (&task); + task.wait (); + return 0; +} +// Listing 2 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadManagement/ExitHandler.cpp b/ACE/examples/APG/ThreadManagement/ExitHandler.cpp new file mode 100644 index 00000000000..85238eac052 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/ExitHandler.cpp @@ -0,0 +1,71 @@ +// $Id$ + +// Listing 1 code/ch13 +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +class ExitHandler : public ACE_At_Thread_Exit +{ +public: + virtual void apply (void) + { + ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) is exiting \n"))); + + // Shut down all devices. + } +}; +// Listing 1 +// Listing 2 code/ch13 +class HA_CommandHandler : public ACE_Task_Base +{ +public: + HA_CommandHandler(ExitHandler& eh) : eh_(eh) + { } + + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting up \n"))); + + this->thr_mgr ()->at_exit (eh_); + + // Do something. + + // Forcefully exit. + ACE_Thread::exit (); + + // NOT REACHED + return 0; + } + +private: + ExitHandler& eh_; +}; +// Listing 2 +// Listing 3 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ExitHandler eh; + + HA_CommandHandler handler (eh); + handler.activate (); + + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +// Listing 3 +#if 0 +// Listing 4 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ExitHandler eh; + ACE_Thread_Manager tm; + + HA_CommandHandler handler (eh); + handler.thr_mgr (&tm); + handler.activate (); + + tm.wait(); + return 0; +} +// Listing 4 +#endif diff --git a/ACE/examples/APG/ThreadManagement/Makefile.am b/ACE/examples/APG/ThreadManagement/Makefile.am new file mode 100644 index 00000000000..0ed91996db2 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Makefile.am @@ -0,0 +1,146 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Async_Cancel.am +noinst_PROGRAMS = Async_Cancel + +Async_Cancel_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Async_Cancel_SOURCES = \ + Async_Cancel.cpp \ + SecurityContext.h + +Async_Cancel_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Coop_Cancel.am +noinst_PROGRAMS += Coop_Cancel + +Coop_Cancel_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Coop_Cancel_SOURCES = \ + Coop_Cancel.cpp \ + SecurityContext.h + +Coop_Cancel_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.ExitHandler.am +noinst_PROGRAMS += ExitHandler + +ExitHandler_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ExitHandler_SOURCES = \ + ExitHandler.cpp \ + SecurityContext.h + +ExitHandler_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Pool.am +noinst_PROGRAMS += Pool + +Pool_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Pool_SOURCES = \ + Pool.cpp \ + SecurityContext.h + +Pool_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Priorities.am +noinst_PROGRAMS += Priorities + +Priorities_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Priorities_SOURCES = \ + Priorities.cpp \ + SecurityContext.h + +Priorities_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Signals.am +noinst_PROGRAMS += Signals + +Signals_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Signals_SOURCES = \ + Signals.cpp \ + SecurityContext.h + +Signals_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Signals2.am +noinst_PROGRAMS += Signals2 + +Signals2_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Signals2_SOURCES = \ + Signals2.cpp \ + SecurityContext.h + +Signals2_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Start_Hook.am +noinst_PROGRAMS += Start_Hook + +Start_Hook_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Start_Hook_SOURCES = \ + Start_Hook.cpp \ + SecurityContext.h + +Start_Hook_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.State.am +noinst_PROGRAMS += State + +State_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +State_SOURCES = \ + State.cpp \ + SecurityContext.h + +State_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/ThreadManagement/Pool.cpp b/ACE/examples/APG/ThreadManagement/Pool.cpp new file mode 100644 index 00000000000..30ae56801a5 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Pool.cpp @@ -0,0 +1,46 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch13 +class HA_CommandHandler : public ACE_Task<ACE_MT_SYNCH> +{ +public: + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting up \n"))); + ACE_Message_Block *mb; + if (this->getq (mb) == -1) + return -1; + // ... do something with the message. + return 0; + } +}; +// Listing 1 +// Listing 2 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_CommandHandler handler; + + // Create 4 threads. + handler.activate (THR_NEW_LWP | THR_JOINABLE, 4); + handler.wait (); + return 0; +} +// Listing 2 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadManagement/Priorities.cpp b/ACE/examples/APG/ThreadManagement/Priorities.cpp new file mode 100644 index 00000000000..3a80a613714 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Priorities.cpp @@ -0,0 +1,104 @@ +// $Id$ + +#include "ace/config-lite.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_unistd.h" + +// Listing 2 code/ch13 +class HA_CommandHandler : public ACE_Task<ACE_MT_SYNCH> +{ +public: + HA_CommandHandler (const char *name) : name_ (name) + { } + + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting up %C\n"), + name_)); + + ACE_OS::sleep (2); + ACE_Message_Block *mb = 0; + while (this->getq (mb) != -1) + { + if (mb->msg_type () == ACE_Message_Block::MB_BREAK) + { + mb->release (); + break; + } + process_message (mb); + mb->release (); + } + return 0; + } + + void process_message (ACE_Message_Block *) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Processing message %C\n"), + name_)); + // Simulate compute bound task. + for (int i = 0; i < 100; i++) + ; + } + +private: + const char *name_; +}; +// Listing 2 + +#if !defined (ACE_THR_PRI_OTHER_MAX) +// This should be fixed in ACE... There's no _MAX, _MIN values for +// thread priorities. +#if defined (ACE_WIN32) +# define ACE_THR_PRI_OTHER_MAX ((ACE_THR_PRI_OTHER_DEF) + 1) +#elif defined (VXWORKS) +# define ACE_THR_PRI_OTHER_MAX 0 +#endif +#endif + +// Listing 1 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_CommandHandler hp_handler ("HighPriority"); + hp_handler.activate (THR_NEW_LWP | THR_JOINABLE, + 1, 1, ACE_THR_PRI_OTHER_MAX); + + HA_CommandHandler lp_handler ("LowPriority"); + lp_handler.activate (THR_NEW_LWP | THR_JOINABLE, + 1, 1, ACE_THR_PRI_OTHER_DEF); + + ACE_Message_Block mb; + for (int i = 0; i < 100; i++) + { + ACE_Message_Block *mb_hp, *mb_lp; + mb_hp = mb.clone (); + mb_lp = mb.clone (); + hp_handler.putq (mb_hp); + lp_handler.putq (mb_lp); + } + + ACE_Message_Block stop (0, ACE_Message_Block::MB_BREAK); + hp_handler.putq (stop.clone ()); + lp_handler.putq (stop.clone ()); + hp_handler.wait (); + lp_handler.wait (); + + return 0; +} +// Listing 1 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadManagement/SecurityContext.h b/ACE/examples/APG/ThreadManagement/SecurityContext.h new file mode 100644 index 00000000000..73adbd1a435 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/SecurityContext.h @@ -0,0 +1,16 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __SECURITYCONTEXT_H_ +#define __SECURITYCONTEXT_H_ + +struct SecurityContext + { + const char * user; + }; + +#endif /* __SECURITYCONTEXT_H_ */ diff --git a/ACE/examples/APG/ThreadManagement/Signals.cpp b/ACE/examples/APG/ThreadManagement/Signals.cpp new file mode 100644 index 00000000000..85547ed3249 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Signals.cpp @@ -0,0 +1,93 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +// Listing 1 code/ch13 +class SignalableTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0) + { + if (signum == SIGUSR1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) received a %S signal\n"), + signum)); + handle_alert (); + } + return 0; + } + + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Starting thread\n"))); + + while (1) + { + ACE_Message_Block* mb = 0; + ACE_Time_Value tv (0, 1000); + tv += ACE_OS::time (0); + int result = this->getq (mb, &tv); + if (result == -1 && errno == EWOULDBLOCK) + continue; + else + process_message (mb); + } + + ACE_NOTREACHED (return 0); + } + + void handle_alert (); + void process_message (ACE_Message_Block *mb); +}; +// Listing 1 + +void +SignalableTask::process_message (ACE_Message_Block *) +{ +} + +void +SignalableTask::handle_alert () +{ +} + +// Listing 2 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + SignalableTask handler; + handler.activate (THR_NEW_LWP | THR_JOINABLE , 5); + + ACE_Sig_Handler sh; + sh.register_handler (SIGUSR1, &handler); + + ACE_OS::sleep (1); + + ACE_Thread_Manager::instance () -> + kill_grp (handler.grp_id (), SIGUSR1); + handler.wait (); + return 0; +} +// Listing 2 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadManagement/Signals2.cpp b/ACE/examples/APG/ThreadManagement/Signals2.cpp new file mode 100644 index 00000000000..0df855c45bb --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Signals2.cpp @@ -0,0 +1,97 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +class SignalableTask : public ACE_Task<ACE_MT_SYNCH> +{ +public: + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0) + { + if (signum == SIGUSR1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) received a %S signal\n"), + signum)); + handle_alert(); + } + + return 0; + } + + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Starting thread\n"))); + + while (1) + { + ACE_Message_Block* mb = 0; + ACE_Time_Value tv (0, 1000); + tv += ACE_OS::time (0); + + int result = this->getq(mb, &tv); + + if (result == -1 && errno == EWOULDBLOCK) + continue; + else + process_message (mb); + } + + ACE_NOTREACHED (return 0); + } + + void handle_alert (); + void process_message (ACE_Message_Block *mb); +}; + +void +SignalableTask::process_message (ACE_Message_Block *) +{ + return; +} + +void +SignalableTask::handle_alert (void) +{ + return; +} + +// Listing 1 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Main thread \n"))); + SignalableTask handler; + handler.activate (THR_NEW_LWP | THR_JOINABLE, 5); + + ACE_Sig_Handler sh; + sh.register_handler (SIGUSR1, &handler); + + ACE_OS::sleep (1); // Allow threads to start + + for (int i = 0; i < 5; i++) + ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); + handler.wait (); + return 0; +} +// Listing 1 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadManagement/Start_Hook.cpp b/ACE/examples/APG/ThreadManagement/Start_Hook.cpp new file mode 100644 index 00000000000..1c4ad0794b7 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/Start_Hook.cpp @@ -0,0 +1,60 @@ +// $Id$ + +#include "ace/Thread_Hook.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +#include "SecurityContext.h" + +// Listing 1 code/ch13 +class HA_ThreadHook : public ACE_Thread_Hook +{ +public: + virtual ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func, void* arg) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) New Thread Spawned\n"))); + + // Create the context on the thread's own stack. + ACE_TSS<SecurityContext> secCtx; + // Special initialization. + add_sec_context_thr (secCtx); + + return (*func) (arg); + } + + void add_sec_context_thr (ACE_TSS<SecurityContext> &secCtx); +}; +// Listing 1 + +void +HA_ThreadHook::add_sec_context_thr(ACE_TSS<SecurityContext> &secCtx) +{ + secCtx->user = 0; +} + + +class HA_CommandHandler : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting up \n"))); + + // Do something. + + return 0; + } +}; +// Listing 2 code/ch13 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_ThreadHook hook; + ACE_Thread_Hook::thread_hook (&hook); + + HA_CommandHandler handler; + handler.activate (); + handler.wait(); + return 0; +} +// Listing 2 + diff --git a/ACE/examples/APG/ThreadManagement/State.cpp b/ACE/examples/APG/ThreadManagement/State.cpp new file mode 100644 index 00000000000..d95433440c7 --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/State.cpp @@ -0,0 +1,39 @@ +// $Id$ + +#include "ace/Task.h" + +class HA_CommandHandler : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("(%t) Handler Thread running\n"))); + return 0; + } +}; + + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Main Thread running\n"))); +// Listing 1 code/ch13 + HA_CommandHandler handler; + int result = handler.activate (THR_NEW_LWP | + THR_JOINABLE | + THR_SUSPENDED); + ACE_ASSERT (result == 0); + + ACE_UNUSED_ARG (result); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) The current thread count is %d\n"), + handler.thr_count ())); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) The group identifier is %d\n"), + handler.grp_id ())); + handler.resume (); + handler.wait (); +// Listing 1 + return 0; +} diff --git a/ACE/examples/APG/ThreadManagement/threadmgmt.mpc b/ACE/examples/APG/ThreadManagement/threadmgmt.mpc new file mode 100644 index 00000000000..bb765150abb --- /dev/null +++ b/ACE/examples/APG/ThreadManagement/threadmgmt.mpc @@ -0,0 +1,65 @@ +// -*- MPC -*- +// $Id$ + +project(Async Cancel) : aceexe { + exename = Async_Cancel + Source_Files { + Async_Cancel.cpp + } +} + +project(Coop Cancel) : aceexe { + exename = Coop_Cancel + Source_Files { + Coop_Cancel.cpp + } +} + +project(ExitHandler) : aceexe { + exename = ExitHandler + Source_Files { + ExitHandler.cpp + } +} + +project(Pool) : aceexe { + exename = Pool + Source_Files { + Pool.cpp + } +} + +project(Priorities) : aceexe { + exename = Priorities + Source_Files { + Priorities.cpp + } +} + +project(Signals) : aceexe { + exename = Signals + Source_Files { + Signals.cpp + } +} + +project(Signals2) : aceexe { + exename = Signals2 + Source_Files { + Signals2.cpp + } +} + +project(Start Hook) : aceexe { + exename = Start_Hook + Source_Files { + Start_Hook.cpp + } +} + +project(State) : aceexe { + exename = State + Source_Files { + State.cpp + } +} diff --git a/ACE/examples/APG/ThreadPools/.cvsignore b/ACE/examples/APG/ThreadPools/.cvsignore new file mode 100644 index 00000000000..7052a85815f --- /dev/null +++ b/ACE/examples/APG/ThreadPools/.cvsignore @@ -0,0 +1,10 @@ +Futures +Futures +LF_ThreadPool +LF_ThreadPool +TP_Reactor +TP_Reactor +Task_ThreadPool +Task_ThreadPool +ThreadPool +ThreadPool diff --git a/ACE/examples/APG/ThreadPools/Futures.cpp b/ACE/examples/APG/ThreadPools/Futures.cpp new file mode 100644 index 00000000000..361a8bb43a2 --- /dev/null +++ b/ACE/examples/APG/ThreadPools/Futures.cpp @@ -0,0 +1,321 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_time.h" +#include "ace/Task.h" +#include "ace/Unbounded_Queue.h" +#include "ace/Synch.h" +#include "ace/SString.h" +#include "ace/Method_Request.h" +#include "ace/Future.h" +#include "ace/Activation_Queue.h" + +#define OUTSTANDING_REQUESTS 20 + +// Listing 2 code/ch16 +class CompletionCallBack: public ACE_Future_Observer<ACE_CString*> +{ +public: + virtual void update (const ACE_Future<ACE_CString*> & future) + { + ACE_CString *result = 0; + + // Block for the result. + future.get (result); + ACE_DEBUG ((LM_INFO, ACE_TEXT("%C\n"), result->c_str ())); + delete result; + } +}; +// Listing 2 +// Listing 1 code/ch16 +class LongWork : public ACE_Method_Request +{ +public: + virtual int call (void) + { + ACE_TRACE (ACE_TEXT ("LongWork::call")); + ACE_DEBUG + ((LM_INFO, ACE_TEXT ("(%t) Attempting long work task\n"))); + ACE_OS::sleep (1); + + char buf[1024]; + ACE_OS::strcpy (buf, "Completed assigned task\n"); + ACE_CString *msg; + ACE_NEW_RETURN + (msg, ACE_CString (buf, ACE_OS::strlen (buf) + 1), -1); + result_.set (msg); + return 0; + } + + ACE_Future<ACE_CString*> &future (void) + { + ACE_TRACE (ACE_TEXT ("LongWork::future")); + return result_; + } + + void attach (CompletionCallBack *cb) + { + result_.attach (cb); + } + +private: + ACE_Future<ACE_CString*> result_; +}; +// Listing 1 + +class Exit : public ACE_Method_Request +{ +public: + virtual int call (void) + { + ACE_TRACE (ACE_TEXT ("Exit::call")); + return -1; + } +}; + +class Worker; + +class IManager +{ +public: + virtual ~IManager (void) { } + + virtual int return_to_work (Worker *worker) = 0; +}; + +// Listing 3 code/ch16 +class Worker: public ACE_Task<ACE_MT_SYNCH> +{ +public: + Worker (IManager *manager) + : manager_(manager), queue_ (msg_queue ()) + { } + + int perform (ACE_Method_Request *req) + { + ACE_TRACE (ACE_TEXT ("Worker::perform")); + return this->queue_.enqueue (req); + } + + virtual int svc (void) + { + thread_id_ = ACE_Thread::self (); + while (1) + { + ACE_Method_Request *request = this->queue_.dequeue(); + if (request == 0) + return -1; + + // Invoke the request + int result = request->call (); + if (result == -1) + break; + + // Return to work. + this->manager_->return_to_work (this); + } + + return 0; + } + + ACE_thread_t thread_id (void); + +private: + IManager *manager_; + ACE_thread_t thread_id_; + ACE_Activation_Queue queue_; +}; +// Listing 3 + +ACE_thread_t Worker::thread_id (void) +{ + return thread_id_; +} + +// Listing 4 code/ch16 +class Manager : public ACE_Task_Base, private IManager +{ +public: + enum {POOL_SIZE = 5, MAX_TIMEOUT = 5}; + + Manager () + : shutdown_(0), workers_lock_(), workers_cond_(workers_lock_) + { + ACE_TRACE (ACE_TEXT ("Manager::TP")); + } + + int perform (ACE_Method_Request *req) + { + ACE_TRACE (ACE_TEXT ("Manager::perform")); + return this->queue_.enqueue (req); + } + + int svc (void) + { + ACE_TRACE (ACE_TEXT ("Manager::svc")); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Manager started\n"))); + + // Create pool when you get in the first time. + create_worker_pool (); + + while (!done ()) + { + ACE_Time_Value tv ((long)MAX_TIMEOUT); + tv += ACE_OS::time (0); + + // Get the next message + ACE_Method_Request *request = this->queue_.dequeue (&tv); + if (request == 0) + { + shut_down (); + break; + } + + // Choose a worker. + Worker *worker = choose_worker (); + + // Ask the worker to do the job. + worker->perform (request); + } + + return 0; + } + + int shut_down (void); + + virtual int return_to_work (Worker *worker) + { + ACE_GUARD_RETURN + (ACE_Thread_Mutex, worker_mon, this->workers_lock_, -1); + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("(%t) Worker returning to work.\n"))); + this->workers_.enqueue_tail (worker); + this->workers_cond_.signal (); + + return 0; + } + +private: + Worker *choose_worker (void) + { + ACE_GUARD_RETURN + (ACE_Thread_Mutex, worker_mon, this->workers_lock_, 0) + + while (this->workers_.is_empty ()) + workers_cond_.wait (); + + Worker *worker = 0; + this->workers_.dequeue_head (worker); + return worker; + } + + int create_worker_pool (void) + { + ACE_GUARD_RETURN + (ACE_Thread_Mutex, worker_mon, this->workers_lock_, -1); + for (int i = 0; i < POOL_SIZE; i++) + { + Worker *worker; + ACE_NEW_RETURN (worker, Worker (this), -1); + this->workers_.enqueue_tail (worker); + worker->activate (); + } + + return 0; + } + + int done (void) + { + return (shutdown_ == 1); + } + + ACE_thread_t thread_id (Worker *worker) + { + return worker->thread_id (); + } + +private: + int shutdown_; + ACE_Thread_Mutex workers_lock_; + ACE_Condition<ACE_Thread_Mutex> workers_cond_; + ACE_Unbounded_Queue<Worker* > workers_; + ACE_Activation_Queue queue_; +}; +// Listing 4 + +int +Manager::shut_down (void) +{ + ACE_TRACE (ACE_TEXT ("Manager::shut_down")); + ACE_Unbounded_Queue<Worker* >::ITERATOR iter = this->workers_.begin (); + Worker **worker_ptr = 0; + do + { + iter.next (worker_ptr); + Worker *worker = (*worker_ptr); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Attempting shutdown of %d\n"), + thread_id (worker))); + + Exit *req; + ACE_NEW_RETURN (req, Exit(), -1); + + // Send the hangup message + worker->perform (req); + + // Wait for the exit. + worker->wait (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Worker %d shut down.\n"), + thread_id (worker))); + + delete req; + delete worker; + + } + while (iter.advance ()); + + shutdown_ = 1; + + return 0; +} + +// Listing 5 code/ch16 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Manager tp; + tp.activate (); + + ACE_Time_Value tv; + tv.msec (100); + + // Wait for a few seconds every time you send a message. + CompletionCallBack cb; + LongWork workArray[OUTSTANDING_REQUESTS]; + for (int i = 0; i < OUTSTANDING_REQUESTS; i++) + { + workArray[i].attach (&cb); + ACE_OS::sleep (tv); + tp.perform (&workArray[i]); + } + + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +// Listing 5 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadPools/LF_ThreadPool.cpp b/ACE/examples/APG/ThreadPools/LF_ThreadPool.cpp new file mode 100644 index 00000000000..820e74c36e8 --- /dev/null +++ b/ACE/examples/APG/ThreadPools/LF_ThreadPool.cpp @@ -0,0 +1,252 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/Task.h" +#include "ace/Containers.h" +#include "ace/Synch.h" + +// Listing 4 code/ch16 +class Follower +{ +public: + Follower (ACE_Thread_Mutex &leader_lock) + : cond_(leader_lock) + { + owner_ = ACE_Thread::self (); + } + + int wait (void) + { + return this->cond_.wait (); + } + + int signal (void) + { + return this->cond_.signal (); + } + + ACE_thread_t owner (void) + { + return this->owner_; + } + +private: + ACE_Condition<ACE_Thread_Mutex> cond_; + ACE_thread_t owner_; +}; +// Listing 4 +// Listing 1 code/ch16 +class LF_ThreadPool : public ACE_Task<ACE_MT_SYNCH> +{ +public: + LF_ThreadPool () : shutdown_(0), current_leader_(0) + { + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::TP")); + } + + virtual int svc (void); + + void shut_down (void) + { + shutdown_ = 1; + } + +private: + int become_leader (void); + + Follower *make_follower (void); + + int elect_new_leader (void); + + int leader_active (void) + { + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::leader_active")); + return this->current_leader_ != 0; + } + + void leader_active (ACE_thread_t leader) + { + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::leader_active")); + this->current_leader_ = leader; + } + + void process_message (ACE_Message_Block *mb); + + int done (void) + { + return (shutdown_ == 1); + } + +private: + int shutdown_; + ACE_thread_t current_leader_; + ACE_Thread_Mutex leader_lock_; + ACE_Unbounded_Queue<Follower*> followers_; + ACE_Thread_Mutex followers_lock_; + static long LONG_TIME; +}; +// Listing 1 +// Listing 2 code/ch16 +int +LF_ThreadPool::svc (void) +{ + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::svc")); + while (!done ()) + { + become_leader (); // Block until this thread is the leader. + + ACE_Message_Block *mb = 0; + ACE_Time_Value tv (LONG_TIME); + tv += ACE_OS::gettimeofday (); + + // Get a message, elect new leader, then process message. + if (this->getq (mb, &tv) < 0) + { + if (elect_new_leader () == 0) + break; + continue; + } + + elect_new_leader (); + process_message (mb); + } + + return 0; +} +// Listing 2 +// Listing 3 code/ch16 +int +LF_ThreadPool::become_leader (void) +{ + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::become_leader")); + + ACE_GUARD_RETURN + (ACE_Thread_Mutex, leader_mon, this->leader_lock_, -1); + if (leader_active ()) + { + Follower *fw = make_follower (); + { + // Wait until told to do so. + while (leader_active ()) + fw->wait (); + } + + delete fw; + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Becoming the leader\n"))); + + // Mark yourself as the active leader. + leader_active (ACE_Thread::self ()); + return 0; +} + +Follower* +LF_ThreadPool::make_follower (void) +{ + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::make_follower")); + + ACE_GUARD_RETURN + (ACE_Thread_Mutex, follower_mon, this->followers_lock_, 0); + Follower *fw; + ACE_NEW_RETURN (fw, Follower (this->leader_lock_), 0); + this->followers_.enqueue_tail (fw); + return fw; +} +// Listing 3 +// Listing 5 code/ch16 +int +LF_ThreadPool::elect_new_leader (void) +{ + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::elect_new_leader")); + + ACE_GUARD_RETURN + (ACE_Thread_Mutex, leader_mon, this->leader_lock_, -1); + leader_active (0); + + // Wake up a follower + if (!followers_.is_empty ()) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, + follower_mon, + this->followers_lock_, + -1); + // Get the old follower. + Follower *fw; + if (this->followers_.dequeue_head (fw) != 0) + return -1; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%t) Resigning and Electing %d\n"), + fw->owner ())); + return (fw->signal () == 0) ? 0 : -1; + } + else + { + ACE_DEBUG + ((LM_ERROR, ACE_TEXT ("(%t) Oops no followers left\n"))); + return -1; + } +} +// Listing 5 + +void +LF_ThreadPool::process_message (ACE_Message_Block *mb) +{ + ACE_TRACE (ACE_TEXT ("LF_ThreadPool::process_message")); + int msgId; + ACE_OS::memcpy (&msgId, mb->rd_ptr (), sizeof(int)); + mb->release (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Started processing message:%d\n"), + msgId)); + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Finished processing message:%d\n"), + msgId)); +} + +long LF_ThreadPool::LONG_TIME = 5L; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + LF_ThreadPool tp; + tp.activate (THR_NEW_LWP| THR_JOINABLE, 5); + + // Wait for a few seconds... + ACE_OS::sleep (2); + ACE_Time_Value tv (1L); + + ACE_Message_Block *mb; + for (int i = 0; i < 30; i++) + { + ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof(int)), -1); + ACE_OS::memcpy (mb->wr_ptr (), &i, sizeof(int)); + ACE_OS::sleep (tv); + + // Add a new work item. + tp.putq (mb); + } + + ACE_Thread_Manager::instance ()->wait (); + + ACE_OS::sleep (10); + + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadPools/Makefile.am b/ACE/examples/APG/ThreadPools/Makefile.am new file mode 100644 index 00000000000..f1167e857c5 --- /dev/null +++ b/ACE/examples/APG/ThreadPools/Makefile.am @@ -0,0 +1,96 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Futures.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Futures + +Futures_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Futures_SOURCES = \ + Futures.cpp \ + Request_Handler.h + +Futures_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.LF_ThreadPool.am +noinst_PROGRAMS += LF_ThreadPool + +LF_ThreadPool_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +LF_ThreadPool_SOURCES = \ + LF_ThreadPool.cpp \ + Request_Handler.h + +LF_ThreadPool_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TP_Reactor.am +noinst_PROGRAMS += TP_Reactor + +TP_Reactor_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +TP_Reactor_SOURCES = \ + TP_Reactor.cpp \ + Request_Handler.h + +TP_Reactor_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Task_ThreadPool.am +noinst_PROGRAMS += Task_ThreadPool + +Task_ThreadPool_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Task_ThreadPool_SOURCES = \ + Task_ThreadPool.cpp \ + Request_Handler.h + +Task_ThreadPool_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.ThreadPool.am +noinst_PROGRAMS += ThreadPool + +ThreadPool_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ThreadPool_SOURCES = \ + ThreadPool.cpp \ + Request_Handler.h + +ThreadPool_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/ThreadPools/Request_Handler.h b/ACE/examples/APG/ThreadPools/Request_Handler.h new file mode 100644 index 00000000000..9965fb7a30e --- /dev/null +++ b/ACE/examples/APG/ThreadPools/Request_Handler.h @@ -0,0 +1,34 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __REQUEST_HANDLER_H_ +#define __REQUEST_HANDLER_H_ + +#include "ace/Svc_Handler.h" +#include "ace/SOCK_Stream.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Thread_Manager; +ACE_END_VERSIONED_NAMESPACE_DECL + +class Request_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> + { + // = TITLE + // This class is the Svc_Handler used by <Acceptor>. + public: + Request_Handler (ACE_Thread_Manager *tm = 0); + // The default constructor makes sure the right reactor is used. + + protected: + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask = 0); + + private: + size_t nr_msgs_rcvd_; + }; + +#endif /* __REQUEST_HANDLER_H_ */ diff --git a/ACE/examples/APG/ThreadPools/TP_Reactor.cpp b/ACE/examples/APG/ThreadPools/TP_Reactor.cpp new file mode 100644 index 00000000000..9c82907a8e6 --- /dev/null +++ b/ACE/examples/APG/ThreadPools/TP_Reactor.cpp @@ -0,0 +1,269 @@ +// == == == == == == == == == == == == == == == == == == == == == == == +// $Id$ +// Stolen from $ACE_ROOT/tests/Thread_Pool_Reactor_Test.cpp +// Thread_Pool_Reactor_Test.cpp, v 1.29 2001/03/20 01:07:21 irfan Exp +// = AUTHOR +// Irfan Pyarali <irfan@cs.wustl.edu> and +// Nanbor Wang <nanbor@cs.wustl.edu> +// == == == == == == == == == == == == == == == == == == == == == == == + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/TP_Reactor.h" + +#include "Request_Handler.h" + +// Accepting end point. This is actually "localhost:10010", but some +// platform couldn't resolve the name so we use the IP address +// directly here. +static const ACE_TCHAR *rendezvous = ACE_TEXT ("127.0.0.1:10010"); + +// Total number of server threads. +static size_t svr_thrno = 5; + +// Total number of client threads. +static size_t cli_runs = 2; + +// Total connection attemps of a client thread. +static size_t cli_conn_no = 2; + +// Total requests a client thread sends. +static size_t cli_req_no = 5; + +// Delay before a thread sending the next request (in msec.) +static int req_delay = 50; + + +typedef ACE_Strategy_Acceptor <Request_Handler, ACE_SOCK_ACCEPTOR> ACCEPTOR; + + +Request_Handler::Request_Handler (ACE_Thread_Manager *thr_mgr) + : ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> (thr_mgr), + nr_msgs_rcvd_(0) +{ + this->reactor (ACE_Reactor::instance ()); +} + +int +Request_Handler::handle_input (ACE_HANDLE fd) +{ + ACE_TCHAR buffer[BUFSIZ]; + ACE_TCHAR len = 0; + ssize_t result = this->peer ().recv (&len, sizeof (ACE_TCHAR)); + + if (result > 0 + && this->peer ().recv_n (buffer, len * sizeof (ACE_TCHAR)) + == static_cast<ssize_t> (len * sizeof (ACE_TCHAR))) + { + ++this->nr_msgs_rcvd_; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) svr input; fd: 0x%x; input: %s\n"), + fd, + buffer)); + if (ACE_OS::strcmp (buffer, ACE_TEXT ("shutdown")) == 0) + ACE_Reactor::instance()->end_reactor_event_loop (); + return 0; + } + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Request_Handler: 0x%x peer closed (0x%x)\n"), + this, fd)); + return -1; +} + +int +Request_Handler::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) svr close; fd: 0x%x, rcvd %d msgs\n"), + fd, + this->nr_msgs_rcvd_)); + + if (this->nr_msgs_rcvd_ != cli_req_no) + ACE_ERROR((LM_ERROR, + ACE_TEXT ("(%t) Handler 0x%x: Expected %d messages; got %d\n"), + this, + cli_req_no, + this->nr_msgs_rcvd_)); + + this->destroy (); + return 0; +} + +// Listing 2 code/ch16 +static int +reactor_event_hook (ACE_Reactor *) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) handling events ....\n"))); + + return 0; +} + +class ServerTP : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Running the event loop\n"))); + + int result = + ACE_Reactor::instance ()->run_reactor_event_loop + (&reactor_event_hook); + + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%t) %p\n"), + ACE_TEXT ("Error handling events")), + 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Done handling events.\n"))); + + return 0; + } +}; +// Listing 2 + +class Client: public ACE_Task_Base + { + public: + Client() + :addr_(rendezvous) + {} + + virtual int svc() + { + ACE_OS::sleep (3); + const ACE_TCHAR *msg = + ACE_TEXT ("Message from Connection worker"); + + ACE_TCHAR buf [BUFSIZ]; + buf[0] = ACE_OS::strlen (msg) + 1; + ACE_OS::strcpy (&buf[1], msg); + + for (size_t i = 0; i < cli_runs; i++) + send_work_to_server(buf); + + shut_down(); + + return 0; + } + + private: + void send_work_to_server(ACE_TCHAR* arg) + { + ACE_SOCK_Stream stream; + ACE_SOCK_Connector connect; + ACE_Time_Value delay (0, req_delay); + size_t len = * reinterpret_cast<ACE_TCHAR *> (arg); + + for (size_t i = 0 ; i < cli_conn_no; i++) + { + if (connect.connect (stream, addr_) < 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%t) %p\n"), + ACE_TEXT ("connect"))); + continue; + } + + for (size_t j = 0; j < cli_req_no; j++) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Sending work to server on handle 0x%x, req %d\n"), + stream.get_handle (), + j+1)); + if (stream.send_n (arg, + (len + 1) * sizeof (ACE_TCHAR)) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%t) %p\n"), + ACE_TEXT ("send_n"))); + continue; + } + ACE_OS::sleep (delay); + } + + stream.close (); + } + + } + + void shut_down() + { + ACE_SOCK_Stream stream; + ACE_SOCK_Connector connect; + + if (connect.connect (stream, addr_) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%t) %p Error while connecting\n"), + ACE_TEXT ("connect"))); + + const ACE_TCHAR *sbuf = ACE_TEXT ("\011shutdown"); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("shutdown stream handle = %x\n"), + stream.get_handle ())); + + if (stream.send_n (sbuf, (ACE_OS::strlen (sbuf) + 1) * sizeof (ACE_TCHAR)) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%t) %p\n"), + ACE_TEXT ("send_n"))); + + stream.close (); + } + private: + ACE_INET_Addr addr_; + }; +// Listing 1 code/ch16 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_TP_Reactor sr; + ACE_Reactor new_reactor (&sr); + ACE_Reactor::instance (&new_reactor); + + ACCEPTOR acceptor; + ACE_INET_Addr accept_addr (rendezvous); + + if (acceptor.open (accept_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open")), + 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Spawning %d server threads...\n"), + svr_thrno)); + + ServerTP serverTP; + serverTP.activate (THR_NEW_LWP | THR_JOINABLE, svr_thrno); + + Client client; + client.activate (); + + ACE_Thread_Manager::instance ()->wait (); + + return 0; +} +// Listing 1 +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadPools/Task_ThreadPool.cpp b/ACE/examples/APG/ThreadPools/Task_ThreadPool.cpp new file mode 100644 index 00000000000..53ebe76b0bc --- /dev/null +++ b/ACE/examples/APG/ThreadPools/Task_ThreadPool.cpp @@ -0,0 +1,149 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_time.h" +#include "ace/Task.h" +#include "ace/Synch.h" +#include "ace/SString.h" + +// Listing 2 code/ch16 +class Workers : public ACE_Task<ACE_MT_SYNCH> +{ +public: + Workers () + { } + + virtual int svc (void) + { + while (1) + { + ACE_Message_Block *mb = 0; + if (this->getq (mb) == -1) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%t) Shutting down\n"))); + break; + } + + // Process the message. + process_message (mb); + } + + return 0; + } + // Listing 2 + +private: + void process_message (ACE_Message_Block *mb) + { + ACE_TRACE (ACE_TEXT ("Workers::process_message")); + int msgId; + ACE_OS::memcpy (&msgId, mb->rd_ptr (), sizeof(int)); + mb->release (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Started processing message %d\n"), + msgId)); + ACE_OS::sleep (3); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Finished processing message %d\n"), + msgId)); + } +}; + +// Listing 1 code/ch16 +class Manager : public ACE_Task<ACE_MT_SYNCH> +{ +public: + enum {POOL_SIZE = 5, MAX_TIMEOUT = 5}; + + Manager () : shutdown_(0) + { + ACE_TRACE (ACE_TEXT ("Manager::Manager")); + } + + int svc (void) + { + ACE_TRACE (ACE_TEXT ("Manager::svc")); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Manager started\n"))); + + // Create pool. + Workers pool; + pool.activate (THR_NEW_LWP | THR_JOINABLE, POOL_SIZE); + + while (!done ()) + { + ACE_Message_Block *mb = 0; + ACE_Time_Value tv ((long)MAX_TIMEOUT); + tv += ACE_OS::time (0); + + // Get a message request. + if (this->getq (mb, &tv) < 0) + { + pool.msg_queue ()->deactivate (); + pool.wait (); + break; + } + + // Ask the worker pool to do the job. + pool.putq (mb); + } + + return 0; + } + +private: + int done (void); + + int shutdown_; +}; +// Listing 1 + +int Manager::done (void) +{ + return (shutdown_ == 1); +} + + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Manager tp; + tp.activate (); + + // Wait for a moment every time you send a message. + ACE_Time_Value tv; + tv.msec (100); + + ACE_Message_Block *mb; + for (int i = 0; i < 30; i++) + { + ACE_NEW_RETURN + (mb, ACE_Message_Block(sizeof(int)), -1); + + ACE_OS::memcpy (mb->wr_ptr (), &i, sizeof(int)); + + ACE_OS::sleep (tv); + + // Add a new work item. + tp.putq (mb); + } + + ACE_Thread_Manager::instance ()->wait (); + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadPools/ThreadPool.cpp b/ACE/examples/APG/ThreadPools/ThreadPool.cpp new file mode 100644 index 00000000000..684762efcbf --- /dev/null +++ b/ACE/examples/APG/ThreadPools/ThreadPool.cpp @@ -0,0 +1,271 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_time.h" +#include "ace/Task.h" +#include "ace/Containers.h" +#include "ace/Synch.h" +#include "ace/SString.h" +#include "ace/Method_Request.h" +#include "ace/Future.h" +#include "ace/Activation_Queue.h" + +class Worker; + +class IManager +{ +public: + virtual ~IManager (void) { } + + virtual int return_to_work (Worker *worker) = 0; +}; + +// Listing 2 code/ch16 +class Worker : public ACE_Task<ACE_MT_SYNCH> +{ +public: + Worker (IManager *manager) : manager_(manager) { } + + virtual int svc (void) + { + thread_id_ = ACE_Thread::self (); + while (1) + { + ACE_Message_Block *mb = 0; + if (this->getq (mb) == -1) + ACE_ERROR_BREAK + ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("getq"))); + if (mb->msg_type () == ACE_Message_Block::MB_HANGUP) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%t) Shutting down\n"))); + mb->release (); + break; + } + // Process the message. + process_message (mb); + // Return to work. + this->manager_->return_to_work (this); + } + + return 0; + } + // Listing 2 + + ACE_thread_t thread_id (void) + { + return thread_id_; + } + +private: + void process_message (ACE_Message_Block *mb) + { + ACE_TRACE (ACE_TEXT ("Worker::process_message")); + int msgId; + ACE_OS::memcpy (&msgId, mb->rd_ptr (), sizeof(int)); + mb->release (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Started processing message %d\n"), + msgId)); + ACE_OS::sleep (3); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Finished processing message %d\n"), + msgId)); + } + + IManager *manager_; + ACE_thread_t thread_id_; +}; + +// Listing 1 code/ch16 +class Manager: public ACE_Task<ACE_MT_SYNCH>, private IManager +{ +public: + enum {POOL_SIZE = 5, MAX_TIMEOUT = 5}; + + Manager () + : shutdown_(0), workers_lock_(), workers_cond_(workers_lock_) + { + ACE_TRACE (ACE_TEXT ("Manager::Manager")); + } + + int svc (void) + { + ACE_TRACE (ACE_TEXT ("Manager::svc")); + + ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Manager started\n"))); + + // Create pool. + create_worker_pool (); + + while (!done ()) + { + ACE_Message_Block *mb = 0; + ACE_Time_Value tv ((long)MAX_TIMEOUT); + tv += ACE_OS::time (0); + + // Get a message request. + if (this->getq (mb, &tv) < 0) + { + shut_down (); + break; + } + + // Choose a worker. + Worker *worker = 0; + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, + worker_mon, this->workers_lock_, -1); + + while (this->workers_.is_empty ()) + workers_cond_.wait (); + + this->workers_.dequeue_head (worker); + } + + // Ask the worker to do the job. + worker->putq (mb); + } + + return 0; + } + + int shut_down (void); + + ACE_thread_t thread_id (Worker *worker); + + virtual int return_to_work (Worker *worker) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, + worker_mon, this->workers_lock_, -1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Worker %d returning to work.\n"), + worker->thr_mgr ()->thr_self ())); + this->workers_.enqueue_tail (worker); + this->workers_cond_.signal (); + + return 0; + } + +private: + int create_worker_pool (void) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, + worker_mon, + this->workers_lock_, + -1); + for (int i = 0; i < POOL_SIZE; i++) + { + Worker *worker; + ACE_NEW_RETURN (worker, Worker (this), -1); + this->workers_.enqueue_tail (worker); + worker->activate (); + } + + return 0; + } + + int done (void); + +private: + int shutdown_; + ACE_Thread_Mutex workers_lock_; + ACE_Condition<ACE_Thread_Mutex> workers_cond_; + ACE_Unbounded_Queue<Worker* > workers_; +}; +// Listing 1 + +int Manager::done (void) +{ + return (shutdown_ == 1); +} + +int +Manager::shut_down (void) +{ + ACE_TRACE (ACE_TEXT ("Manager::shut_down")); + ACE_Unbounded_Queue<Worker* >::ITERATOR iter = + this->workers_.begin (); + Worker **worker_ptr = 0; + do + { + iter.next (worker_ptr); + Worker *worker = (*worker_ptr); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Attempting shutdown of %d\n"), + thread_id (worker))); + + // Send the hangup message. + ACE_Message_Block *mb; + ACE_NEW_RETURN + (mb, + ACE_Message_Block(0, + ACE_Message_Block::MB_HANGUP), + -1); + worker->putq (mb); + + // Wait for the exit. + worker->wait (); + + ACE_ASSERT (worker->msg_queue ()->is_empty ()); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Worker %d shut down.\n)"), + thread_id (worker))); + delete worker; + } + while (iter.advance ()); + + shutdown_ = 1; + + return 0; +} + +ACE_thread_t +Manager::thread_id (Worker *worker) +{ + return worker->thread_id (); +} + + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + Manager tp; + tp.activate (); + + // Wait for a moment every time you send a message. + ACE_Time_Value tv; + tv.msec (100); + + ACE_Message_Block *mb; + for (int i = 0; i < 30; i++) + { + ACE_NEW_RETURN + (mb, ACE_Message_Block(sizeof(int)), -1); + + ACE_OS::memcpy (mb->wr_ptr (), &i, sizeof(int)); + + ACE_OS::sleep (tv); + + // Add a new work item. + tp.putq (mb); + } + + ACE_Thread_Manager::instance ()->wait (); + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadPools/threadpools.mpc b/ACE/examples/APG/ThreadPools/threadpools.mpc new file mode 100644 index 00000000000..1bb9a860920 --- /dev/null +++ b/ACE/examples/APG/ThreadPools/threadpools.mpc @@ -0,0 +1,38 @@ +// -*- MPC -*- +// $Id$ + +project(Futures) : aceexe { + avoids += ace_for_tao + exename = Futures + Source_Files { + Futures.cpp + } +} + +project(LF ThreadPool) : aceexe { + exename = LF_ThreadPool + Source_Files { + LF_ThreadPool.cpp + } +} + +project(Task ThreadPool) : aceexe { + exename = Task_ThreadPool + Source_Files { + Task_ThreadPool.cpp + } +} + +project(ThreadPool) : aceexe { + exename = ThreadPool + Source_Files { + ThreadPool.cpp + } +} + +project(TP Reactor) : aceexe { + exename = TP_Reactor + Source_Files { + TP_Reactor.cpp + } +} diff --git a/ACE/examples/APG/ThreadSafety/.cvsignore b/ACE/examples/APG/ThreadSafety/.cvsignore new file mode 100644 index 00000000000..7fe1b99d03f --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/.cvsignore @@ -0,0 +1,16 @@ +Atomic_Op +Atomic_Op +Barrier +Barrier +Mutex +Mutex +RW_Lock +RW_Lock +Semaphore +Semaphore +TSS +TSS +Tokens +Tokens +Tokens_Deadlock +Tokens_Deadlock diff --git a/ACE/examples/APG/ThreadSafety/Atomic_Op.cpp b/ACE/examples/APG/ThreadSafety/Atomic_Op.cpp new file mode 100644 index 00000000000..d315d433a66 --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Atomic_Op.cpp @@ -0,0 +1,127 @@ +// $Id$ + +#include "ace/Synch.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Atomic_Op.h" + +#if defined(RUNNING_ON_UNSAFE_MULTIPROCESSOR) +// Listing 1 code/ch14 +typedef ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> SafeUInt; +// Listing 1 +// Listing 2 code/ch14 +typedef ACE_Atomic_Op<ACE_Thread_Mutex, int> SafeInt; +// Listing 2 +#else +typedef ACE_Atomic_Op<ACE_Null_Mutex, unsigned int> SafeUInt; +typedef ACE_Atomic_Op<ACE_Null_Mutex, int> SafeInt; +#endif /* RUNNING_ON_UNSAFE_MULTIPROCESSOR) */ + +static const unsigned int Q_SIZE = 2; +static const int MAX_PROD = 10; + +// Listing 3 code/ch14 +class Producer : public ACE_Task_Base +{ +public: + Producer (int *buf, SafeUInt &in, SafeUInt &out) + : buf_(buf), in_(in), out_(out) + { } + + int svc (void) + { + SafeInt itemNo = 0; + while (1) + { + // Busy wait. + do + { } + while (in_.value () - out_.value () == Q_SIZE); + + itemNo++; + buf_[in_.value () % Q_SIZE] = itemNo.value (); + in_++; + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Produced %d \n"), + itemNo.value ())); + + if (check_termination (itemNo.value ())) + break; + } + + return 0; + } + + int check_termination (int item) + { + return (item == MAX_PROD); + } + +private: + int * buf_; + SafeUInt& in_; + SafeUInt& out_; +}; + +class Consumer : public ACE_Task_Base +{ +public: + Consumer (int *buf, SafeUInt &in, SafeUInt& out) + : buf_(buf), in_(in), out_(out) + { } + + int svc (void) + { + while (1) + { + int item; + + // Busy wait. + do + { } + while (in_.value () - out_.value () == 0); + + item = buf_[out_.value () % Q_SIZE]; + out_++; + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Consumed %d\n"), + item)); + + if (check_termination (item)) + break; + } + + return 0; + } + + int check_termination (int item) + { + return (item == MAX_PROD); + } + +private: + int * buf_; + SafeUInt& in_; + SafeUInt& out_; +}; +// Listing 3 + +// Listing 4 code/ch14 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + int shared_buf[Q_SIZE]; + SafeUInt in = 0; + SafeUInt out = 0; + + Producer producer (shared_buf, in, out); + Consumer consumer (shared_buf, in, out); + + producer.activate(); + consumer.activate(); + producer.wait(); + consumer.wait(); + + return 0; +} +// Listing 4 + diff --git a/ACE/examples/APG/ThreadSafety/Barrier.cpp b/ACE/examples/APG/ThreadSafety/Barrier.cpp new file mode 100644 index 00000000000..b07a08f0cee --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Barrier.cpp @@ -0,0 +1,91 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_time.h" +#include "ace/Task.h" +#include "ace/Synch.h" + +// Listing 2 code/ch14 +class HA_CommandHandler : public ACE_Task<ACE_MT_SYNCH> +{ +public: + enum { N_THREADS = 5 }; + + HA_CommandHandler (ACE_Barrier& startup_barrier, + ACE_Barrier &shutdown_barrier) + : startup_barrier_(startup_barrier), + shutdown_barrier_(shutdown_barrier) + { } + + void initialize_handler (void); + int handle_command_requests (void); + + int svc (void) + { + initialize_handler (); + startup_barrier_.wait (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t: %D) Started\n"))); + + while (handle_command_requests () > 0) + ; + + shutdown_barrier_.wait (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t: %D) Ended\n"))); + + return 0; + } + +private: + ACE_Barrier& startup_barrier_; + ACE_Barrier& shutdown_barrier_; +}; +// Listing 2 + +void +HA_CommandHandler::initialize_handler (void) +{ + ACE_Time_Value tv (0, ACE_OS::rand () * 100); + timespec_t t = (timespec_t)tv; + ACE_OS::nanosleep (&t); +} + +int +HA_CommandHandler::handle_command_requests (void) +{ + ACE_Time_Value tv (0, ACE_OS::rand () * 100); + timespec_t t = (timespec_t)tv; + + // Simulate work. + ACE_OS::nanosleep (&t); + + return -1; +} + +// Listing 1 code/ch14 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Barrier startup_barrier (HA_CommandHandler::N_THREADS); + ACE_Barrier shutdown_barrier (HA_CommandHandler::N_THREADS); + + HA_CommandHandler handler (startup_barrier, shutdown_barrier); + handler.activate (THR_NEW_LWP | THR_JOINABLE, + HA_CommandHandler::N_THREADS); + handler.wait (); + return 0; +} +// Listing 1 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadSafety/ClientContext.h b/ACE/examples/APG/ThreadSafety/ClientContext.h new file mode 100644 index 00000000000..bcd58fc4599 --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/ClientContext.h @@ -0,0 +1,30 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __CLIENTCONTEXT_H_ +#define __CLIENTCONTEXT_H_ + +#include "ace/Hash_Map_Manager.h" +#include "ace/Synch.h" + +typedef ACE_Hash_Map_Manager<const char *, void *, ACE_Null_Mutex> +Map; + +// Listing 1 code/ch14 +// Client-specific context information. +class ClientContext +{ +public: + void *get_attribute (const char *name); + void set_attribute (const char *name, void *value); + +private: + Map attributeMap_; +}; +// Listing 1 + +#endif /* __CLIENTCONTEXT_H_ */ diff --git a/ACE/examples/APG/ThreadSafety/Makefile.am b/ACE/examples/APG/ThreadSafety/Makefile.am new file mode 100644 index 00000000000..e7c52980171 --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Makefile.am @@ -0,0 +1,141 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.Atomic_Op.am +noinst_PROGRAMS = Atomic_Op + +Atomic_Op_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Atomic_Op_SOURCES = \ + Atomic_Op.cpp \ + ClientContext.h + +Atomic_Op_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Barrier.am +noinst_PROGRAMS += Barrier + +Barrier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Barrier_SOURCES = \ + Barrier.cpp \ + ClientContext.h + +Barrier_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Mutex.am +noinst_PROGRAMS += Mutex + +Mutex_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Mutex_SOURCES = \ + Mutex.cpp \ + ClientContext.h + +Mutex_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.RW_Lock.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += RW_Lock + +RW_Lock_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +RW_Lock_SOURCES = \ + RW_Lock.cpp \ + ClientContext.h + +RW_Lock_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Semaphore.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Semaphore + +Semaphore_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Semaphore_SOURCES = \ + Semaphore.cpp \ + ClientContext.h + +Semaphore_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.TSS.am +noinst_PROGRAMS += TSS + +TSS_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +TSS_SOURCES = \ + TSS.cpp \ + ClientContext.h + +TSS_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Tokens.am +noinst_PROGRAMS += Tokens + +Tokens_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Tokens_SOURCES = \ + Tokens.cpp \ + ClientContext.h + +Tokens_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Tokens_Deadlock.am +noinst_PROGRAMS += Tokens_Deadlock + +Tokens_Deadlock_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Tokens_Deadlock_SOURCES = \ + Tokens_Deadlock.cpp \ + ClientContext.h + +Tokens_Deadlock_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/ThreadSafety/Mutex.cpp b/ACE/examples/APG/ThreadSafety/Mutex.cpp new file mode 100644 index 00000000000..aa21665222c --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Mutex.cpp @@ -0,0 +1,73 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Synch.h" + +class LogMessage +{ +public: + enum { CRITICAL, NORMAL}; + + virtual ~LogMessage () + { + } + + virtual int priority (void) + { + return NORMAL; + } +}; + +class CriticalLogMessage : public LogMessage +{ + virtual int priority (void) + { + return LogMessage::CRITICAL; + } +}; + +// Listing 1 code/ch14 +typedef ACE_Thread_Mutex MUTEX; +class Logger +{ +public: + void log (LogMessage *msg) + { + ACE_GUARD (MUTEX, mon, mutex_); + if (msg->priority () == LogMessage::CRITICAL) + logCritical (msg); + } + + void logCritical (LogMessage *) + { + // Acquires the same mutex as log()! + ACE_GUARD(MUTEX, mon, mutex_); + } + +private: + MUTEX mutex_; +}; + +static Logger logger; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + CriticalLogMessage cm; + logger.log(&cm); // Will cause deadlock. + return 0; +} +// Listing 1 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadSafety/RW_Lock.cpp b/ACE/examples/APG/ThreadSafety/RW_Lock.cpp new file mode 100644 index 00000000000..83f1287bbdb --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/RW_Lock.cpp @@ -0,0 +1,139 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Synch.h" +#include "ace/Containers.h" +#include "ace/Task.h" + +class Device +{ +public: + Device (int id) : id_(id) + { } + + int id_; +}; + +typedef ACE_DLList<Device> DeviceList; +typedef ACE_DLList_Iterator<Device> DeviceListIterator; + +// Listing 1 code/ch14 +class HA_DiscoveryAgent +{ +public: + void add_device (Device *device) + { + ACE_WRITE_GUARD (ACE_RW_Thread_Mutex, mon, rwmutex_); + list_add_item_i (device); + } + + void remove_device (Device *device) + { + ACE_READ_GUARD (ACE_RW_Thread_Mutex, mon, rwmutex_); + list_remove_item_i(device); + } + + int contains_device (Device *device) + { + ACE_READ_GUARD_RETURN + (ACE_RW_Thread_Mutex, mon, rwmutex_, -1); + return list_contains_item_i (device); + } + +private: + void list_add_item_i (Device * device); + int list_contains_item_i (Device * device); + void list_remove_item_i (Device* device); + +private: + DeviceList deviceList_; + ACE_RW_Thread_Mutex rwmutex_; +}; +// Listing 1 + +void +HA_DiscoveryAgent::list_add_item_i (Device *device) +{ + deviceList_.insert_tail (device); +} + +int +HA_DiscoveryAgent::list_contains_item_i (Device *device) +{ + DeviceListIterator iter (deviceList_); + while (!iter.done ()) + { + if (iter.next () == device) + return 1; + iter++; + } + + return 0; +} + +void +HA_DiscoveryAgent::list_remove_item_i (Device *device) +{ + DeviceListIterator iter (deviceList_); + while (!iter.done ()) + { + if (iter.next () == device) + { + iter.remove (); + break; + } + iter++; + } +} + +static Device *devices[100]; + +class Runner : public ACE_Task_Base +{ +public: + Runner(HA_DiscoveryAgent &agent) : agent_(agent) + { } + + virtual int svc (void) + { + ACE_ASSERT(agent_.contains_device(devices[9]) == 1); + agent_.remove_device (devices[9]); + ACE_ASSERT(agent_.contains_device(devices[9]) == 0); + return 0; + } + +private: + HA_DiscoveryAgent &agent_; +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_DiscoveryAgent agent; + + for (int i = 0; i < 100; i++) + { + devices[i] = new Device (i); + agent.add_device (devices[i]); + } + + Runner runner (agent); + runner.activate (); + + runner.wait (); + + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadSafety/Semaphore.cpp b/ACE/examples/APG/ThreadSafety/Semaphore.cpp new file mode 100644 index 00000000000..47a85d86874 --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Semaphore.cpp @@ -0,0 +1,147 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" +#include "ace/Task.h" +#include "ace/Synch.h" + +// Listing 2 code/ch14 +class Consumer : public ACE_Task<ACE_MT_SYNCH> +{ +public: + enum { N_THREADS = 5 }; + + Consumer (ACE_Semaphore& psema, ACE_Semaphore& csema) + : psema_(psema), csema_(csema), exit_condition_(0) + { } + + int svc (void) + { + while (!is_closed ()) + consume_item (); + return 0; + } + + void consume_item () + { + csema_.acquire (); + if (!is_closed ()) + { + ACE_Message_Block *mb; + this->getq (mb); + if (mb->msg_type () == ACE_Message_Block::MB_HANGUP) + { + shutdown (); + mb->release (); + return; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Consumed %d\n"), + *((int*)mb->rd_ptr ()))); + mb->release(); + } + psema_.release (); + } + } + + void shutdown (void) + { + exit_condition_ = 1; + this->msg_queue ()->deactivate (); + csema_.release (N_THREADS); + } + + int is_closed (void) + { + return exit_condition_; + } + +private: + ACE_Semaphore& psema_; + ACE_Semaphore& csema_; + int exit_condition_; +}; +// Listing 2 +// Listing 1 code/ch14 +class Producer : public ACE_Task_Base +{ +public: + enum { MAX_PROD = 128 }; + + Producer (ACE_Semaphore& psema, ACE_Semaphore& csema, + Consumer &consumer) + : psema_(psema), csema_(csema), consumer_(consumer) + { } + + int svc (void) + { + for (int i = 0; i <= MAX_PROD; i++) + produce_item (i); + hang_up (); + return 0; + } + + void produce_item (int item) + { + psema_.acquire (); + ACE_Message_Block *mb + = new ACE_Message_Block (sizeof (int), + ACE_Message_Block::MB_DATA); + ACE_OS::memcpy (mb->wr_ptr (), &item, sizeof item); + mb->wr_ptr (sizeof (int)); + this->consumer_.putq (mb); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Produced %d\n"), item)); + csema_.release(); + } + + void hang_up () + { + psema_.acquire (); + ACE_Message_Block *mb = + new ACE_Message_Block (0, ACE_Message_Block::MB_HANGUP); + this->consumer_.putq (mb); + csema_.release (); + } + +private: + ACE_Semaphore& psema_; + ACE_Semaphore& csema_; + Consumer& consumer_; +}; +// Listing 1 +// Listing 3 code/ch14 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Semaphore psem (5); + ACE_Semaphore csem (0); + + Consumer consumer (psem, csem); + Producer producer (psem, csem, consumer); + + producer.activate (); + consumer.activate (THR_NEW_LWP | THR_JOINABLE, + Consumer::N_THREADS); + + producer.wait (); + consumer.wait (); + + return 0; +} +// Listing 3 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadSafety/TSS.cpp b/ACE/examples/APG/ThreadSafety/TSS.cpp new file mode 100644 index 00000000000..8cc875cb3ee --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/TSS.cpp @@ -0,0 +1,75 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Synch.h" +#include "ace/Task.h" +#include "ClientContext.h" + + +void* +ClientContext::get_attribute (const char *name) +{ + void * value = 0; + attributeMap_.find (name, value); + return value; +} + +void +ClientContext::set_attribute (const char *name, void *value) +{ + attributeMap_.bind (name, value); +} + +// Listing 2 code/ch14 +class HA_CommandHandler : public ACE_Task<ACE_MT_SYNCH> +{ +public: + virtual int svc (void) + { + ACE_thread_t tid = this->thr_mgr ()->thr_self (); + // Set our identifier in TSS. + this->tss_ctx_->set_attribute ("thread_id", &tid); + + while (handle_requests () > 0) + ; + + return 0; + } + + int handle_requests (void) + { + ACE_thread_t *tid = + (ACE_thread_t*)this->tss_ctx_->get_attribute ("thread_id"); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) TSS TID: %d \n"), + *tid)); + + // do work. + return -1; + } + +private: + ACE_TSS<ClientContext> tss_ctx_; +}; +// Listing 2 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_CommandHandler handler; + handler.activate (THR_NEW_LWP | THR_JOINABLE, 5); + handler.wait (); + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/ThreadSafety/Tokens.cpp b/ACE/examples/APG/ThreadSafety/Tokens.cpp new file mode 100644 index 00000000000..13adff1febb --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Tokens.cpp @@ -0,0 +1,102 @@ +// $Id$ + +#include "ace/Local_Tokens.h" +#include "ace/Token_Manager.h" +#include "ace/Task.h" +#include "ace/OS_NS_time.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +class Device; + +// Listing 1 code/ch14 +class HA_Device_Repository +{ +public: + + enum { N_DEVICES = 100 }; + + HA_Device_Repository () + { + for (int i = 0; i < N_DEVICES; i++) + tokens_[i] = new ACE_Local_Mutex (0, 0, 1); + } + + ~HA_Device_Repository () + { + for (int i = 0; i < N_DEVICES; i++) + delete tokens_[i]; + } + + int update_device (int device_id, char *commands) + { + this->tokens_[device_id]->acquire (); + + Device *curr_device = this->devices_[device_id]; + internal_do (curr_device); + + this->tokens_[device_id]->release (); + + return 0; + } + + void internal_do (Device *device); + +private: + Device *devices_[N_DEVICES]; + ACE_Local_Mutex *tokens_[N_DEVICES]; + unsigned int seed_; +}; +// Listing 1 + +void +HA_Device_Repository::internal_do (Device *device) +{ + ACE_UNUSED_ARG (device); // Real code would use this. + ACE_Time_Value tv (0, ACE_OS::rand_r (this->seed_) % 10000); + timespec_t t = (timespec_t)tv; + ACE_OS::nanosleep (&t); +} + +// Listing 2 code/ch14 +class HA_CommandHandler : public ACE_Task_Base +{ +public: + enum { N_THREADS = 5 }; + + HA_CommandHandler (HA_Device_Repository &rep) : rep_(rep) + { } + + int svc (void) + { + for (int i = 0; i < HA_Device_Repository::N_DEVICES; i++) + rep_.update_device (i, ""); + return 0; + } + +private: + HA_Device_Repository &rep_; +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_Device_Repository rep; + HA_CommandHandler handler (rep); + handler.activate (THR_NEW_LWP | THR_JOINABLE, + HA_CommandHandler::N_THREADS); + handler.wait (); + return 0; +} +// Listing 2 + +#else /* defined (ACE_HAS_TOKENS_LIBRARY) */ + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("local tokens not supported ") + ACE_TEXT ("on this platform\n"))); + return 0; +} + +#endif /* defined (ACE_HAS_TOKENS_LIBRARY) */ diff --git a/ACE/examples/APG/ThreadSafety/Tokens_Deadlock.cpp b/ACE/examples/APG/ThreadSafety/Tokens_Deadlock.cpp new file mode 100644 index 00000000000..f6c6d22491f --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/Tokens_Deadlock.cpp @@ -0,0 +1,69 @@ +// $Id$ + +#include "ace/Local_Tokens.h" +#include "ace/Task.h" +#include "ace/OS_NS_unistd.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +// Listing 1 code/ch14 +class ThreadOne : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_Local_Mutex mutex1 (ACE_TEXT ("resource1"), + 0, // Deadlock detection enabled. + 1);// Debugging enabled. + mutex1.acquire (); + ACE_OS::sleep (2); + ACE_Local_Mutex mutex2 (ACE_TEXT ("resource2"), 0, 1); + mutex2.acquire (); + return 0; + } +}; + +class ThreadTwo : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_Local_Mutex mutex2 (ACE_TEXT ("resource2"), + 0, // Deadlock detection enabled. + 1);// Debugging enabled. + mutex2.acquire (); + ACE_OS::sleep (2); + ACE_Local_Mutex mutex1 (ACE_TEXT ("resource1"), + 0, // Deadlock detection enabled. + 1);// Debugging enabled. + mutex1.acquire (); + return 0; + } +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ThreadOne t1; + ThreadTwo t2; + + t1.activate (); + ACE_OS::sleep (1); + t2.activate (); + t1.wait (); + t2.wait (); + + return 0; +} +// Listing 1 + +#else /* defined (ACE_HAS_TOKENS_LIBRARY) */ + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("local tokens not supported ") + ACE_TEXT ("on this platform\n"))); + return 0; +} + +#endif /* defined (ACE_HAS_TOKENS_LIBRARY) */ diff --git a/ACE/examples/APG/ThreadSafety/threadsafety.mpc b/ACE/examples/APG/ThreadSafety/threadsafety.mpc new file mode 100644 index 00000000000..3598d274917 --- /dev/null +++ b/ACE/examples/APG/ThreadSafety/threadsafety.mpc @@ -0,0 +1,60 @@ +// -*- MPC -*- +// $Id$ + +project(Atomic Op) : aceexe { + exename = Atomic_Op + Source_Files { + Atomic_Op.cpp + } +} + +project(Barrier) : aceexe { + exename = Barrier + Source_Files { + Barrier.cpp + } +} + +project(Mutex) : aceexe { + exename = Mutex + Source_Files { + Mutex.cpp + } +} + +project(RW Lock) : aceexe { + avoids += ace_for_tao + exename = RW_Lock + Source_Files { + RW_Lock.cpp + } +} + +project(Semaphore) : aceexe { + avoids += ace_for_tao + exename = Semaphore + Source_Files { + Semaphore.cpp + } +} + +project(Tokens) : aceexe { + exename = Tokens + Source_Files { + Tokens.cpp + } +} + +project(Tokens Deadlock) : aceexe { + exename = Tokens_Deadlock + Source_Files { + Tokens_Deadlock.cpp + } +} + +project(TSS) : aceexe { + exename = TSS + Source_Files { + TSS.cpp + } +} diff --git a/ACE/examples/APG/Threads/.cvsignore b/ACE/examples/APG/Threads/.cvsignore new file mode 100644 index 00000000000..feb9ec3ab97 --- /dev/null +++ b/ACE/examples/APG/Threads/.cvsignore @@ -0,0 +1,12 @@ +Activate +Activate +Condition_Variables +Condition_Variables +Guards +Guards +Message_Blocks +Message_Blocks +Message_Queue +Message_Queue +Mutexes +Mutexes diff --git a/ACE/examples/APG/Threads/Activate.cpp b/ACE/examples/APG/Threads/Activate.cpp new file mode 100644 index 00000000000..2afa6316f91 --- /dev/null +++ b/ACE/examples/APG/Threads/Activate.cpp @@ -0,0 +1,33 @@ +// $Id$ + +// Listing 1 code/ch12 +#include "ace/Task.h" +#include "ace/OS_NS_unistd.h" + +class HA_CommandHandler : public ACE_Task_Base +{ +public: + virtual int svc (void) + { + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("(%t) Handler Thread running\n"))); + ACE_OS::sleep (4); + return 0; + } +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("(%t) Main Thread running\n"))); + + HA_CommandHandler handler; + int result = handler.activate (); + ACE_ASSERT (result == 0); + + ACE_UNUSED_ARG (result); + + handler.wait (); + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Threads/Condition_Variables.cpp b/ACE/examples/APG/Threads/Condition_Variables.cpp new file mode 100644 index 00000000000..ccb29895032 --- /dev/null +++ b/ACE/examples/APG/Threads/Condition_Variables.cpp @@ -0,0 +1,118 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Task.h" +#include "ace/Synch.h" + +// Listing 1 code/ch12 +class HA_Device_Repository +{ +public: + HA_Device_Repository() : owner_(0) + { } + + int is_free (void) + { return (this->owner_ == 0); } + + int is_owner (ACE_Task_Base* tb) + { return (this->owner_ == tb); } + + ACE_Task_Base *get_owner (void) + { return this->owner_; } + + void set_owner (ACE_Task_Base *owner) + { this->owner_ = owner; } + + int update_device (int device_id); + +private: + ACE_Task_Base * owner_; +}; +// Listing 1 + +class HA_CommandHandler : public ACE_Task_Base +{ +public: + enum {NUM_USES = 10}; + + HA_CommandHandler (HA_Device_Repository& rep, + ACE_Condition<ACE_Thread_Mutex> &wait, + ACE_Thread_Mutex& mutex) + : rep_(rep), waitCond_(wait), mutex_(mutex) + { } + + virtual int svc (void); + +private: + HA_Device_Repository &rep_; + ACE_Condition<ACE_Thread_Mutex> &waitCond_; + ACE_Thread_Mutex &mutex_; +}; +// Listing 2 code/ch12 +int +HA_CommandHandler::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) Handler Thread running\n"))); + + for (int i = 0; i < NUM_USES; i++) + { + this->mutex_.acquire (); + while (!this->rep_.is_free ()) + this->waitCond_.wait (); + this->rep_.set_owner (this); + this->mutex_.release (); + + this->rep_.update_device (i); + + ACE_ASSERT (this->rep_.is_owner (this)); + this->rep_.set_owner (0); + + this->waitCond_.signal (); + } + + return 0; +} +// Listing 2 +int +HA_Device_Repository::update_device (int device_id) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Updating device %d\n"), + device_id)); + + ACE_OS::sleep (1); + return 0; +} +// Listing 3 code/ch12 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_Device_Repository rep; + ACE_Thread_Mutex rep_mutex; + ACE_Condition<ACE_Thread_Mutex> wait (rep_mutex); + + HA_CommandHandler handler1 (rep, wait, rep_mutex); + HA_CommandHandler handler2 (rep, wait, rep_mutex); + + handler1.activate (); + handler2.activate (); + + handler1.wait (); + handler2.wait (); + + return 0; +} +// Listing 3 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Threads/Guards.cpp b/ACE/examples/APG/Threads/Guards.cpp new file mode 100644 index 00000000000..7ef23e1e4da --- /dev/null +++ b/ACE/examples/APG/Threads/Guards.cpp @@ -0,0 +1,95 @@ +// $Id$ +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_main.h" +#include "ace/OS_Memory.h" +#include "ace/Guard_T.h" +#include "ace/Log_Msg.h" +#include "ace/Thread_Mutex.h" + +// This file exists primarily to get code into the book to show different +// ways to do the same thing. For complete context and explanation, please +// see APG chapter 12. + +class HA_Device_Repository { +public: + int update_device (int device_id); + +private: + ACE_Thread_Mutex mutex_; +}; + +class Object { +}; +static Object *object; + +#if 0 +// This is less-desired way to do this... + +// Listing 1 code/ch12 +int +HA_Device_Repository::update_device (int device_id) +{ + this->mutex_.acquire (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Updating device %d\n"), + device_id)); + + // Allocate a new object. + ACE_NEW_RETURN (object, Object, -1); + // ... + // Use the object + + this->mutex_.release (); +} +// Listing 1 +// Listing 2 code/ch12 +int +HA_Device_Repository::update_device (int device_id) +{ + // Construct a guard specifying the type of the mutex as + // a template parameter and passing in the mutex to hold + // as a parameter. + ACE_Guard<ACE_Thread_Mutex> guard (this->mutex_); + + // This can throw an exception that is not caught here. + ACE_NEW_RETURN (object, Object, -1); + // .. + // Use the object. + // .. + // Guard is destroyed, automatically releasing the lock. +} +// Listing 2 +#endif /* 0 */ + +// Listing 3 code/ch12 +int +HA_Device_Repository::update_device (int /* device_id */) +{ + ACE_GUARD_RETURN (ACE_Thread_Mutex, mon, mutex_, -1); + + ACE_NEW_RETURN (object, Object, -1); + // Use the object. + // ... + return 0; +} +// Listing 3 + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_Device_Repository rep; + rep.update_device (42); + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Threads/Makefile.am b/ACE/examples/APG/Threads/Makefile.am new file mode 100644 index 00000000000..a5a1b77d76a --- /dev/null +++ b/ACE/examples/APG/Threads/Makefile.am @@ -0,0 +1,104 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Activate.am +noinst_PROGRAMS = Activate + +Activate_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Activate_SOURCES = \ + Activate.cpp \ + Message_Receiver.h + +Activate_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Condition_Variables.am +noinst_PROGRAMS += Condition_Variables + +Condition_Variables_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Condition_Variables_SOURCES = \ + Condition_Variables.cpp \ + Message_Receiver.h + +Condition_Variables_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Guards.am +noinst_PROGRAMS += Guards + +Guards_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Guards_SOURCES = \ + Guards.cpp \ + Message_Receiver.h + +Guards_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Message_Blocks.am +noinst_PROGRAMS += Message_Blocks + +Message_Blocks_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Message_Blocks_SOURCES = \ + Message_Blocks.cpp \ + Message_Receiver.h + +Message_Blocks_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Message_Queue.am +noinst_PROGRAMS += Message_Queue + +Message_Queue_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Message_Queue_SOURCES = \ + Message_Queue.cpp \ + Message_Receiver.h + +Message_Queue_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Mutexes.am +noinst_PROGRAMS += Mutexes + +Mutexes_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Mutexes_SOURCES = \ + Mutexes.cpp \ + Message_Receiver.h + +Mutexes_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Threads/Message_Blocks.cpp b/ACE/examples/APG/Threads/Message_Blocks.cpp new file mode 100644 index 00000000000..96cbf3e8cfe --- /dev/null +++ b/ACE/examples/APG/Threads/Message_Blocks.cpp @@ -0,0 +1,50 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" + +int ACE_TMAIN (int, ACE_TCHAR **) +{ +#if 0 +// Just for the book... + +// Listing 1 code/ch12 + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (128), -1); + + const char *deviceAddr= "Dev#12"; + mb->copy (deviceAddr, ACE_OS::strlen (deviceAddr)+1); +// Listing 1 +#endif /* 0 */ +// Listing 2 code/ch12 + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (128), -1); + + const char *commandSeq= "CommandSeq#14"; + ACE_OS::sprintf (mb->wr_ptr (), commandSeq); + // Move the wr_ptr() forward in the buffer by the + // amount of data we just put in. + mb->wr_ptr (ACE_OS::strlen (commandSeq) +1); +// Listing 2 +// Listing 3 code/ch12 + ACE_DEBUG((LM_DEBUG, + ACE_TEXT ("Command Sequence --> %C\n"), + mb->rd_ptr ())); + mb->rd_ptr (ACE_OS::strlen (mb->rd_ptr ())+1); + mb->release (); +// Listing 3 +// Listing 4 code/ch12 + // Send a hangup notification to the receiver. + ACE_NEW_RETURN + (mb, ACE_Message_Block (128, ACE_Message_Block::MB_HANGUP), -1); + // Send an error notification to the receiver. + mb->msg_type (ACE_Message_Block::MB_ERROR); +// Listing 4 + mb->release (); + + return 0; +} diff --git a/ACE/examples/APG/Threads/Message_Queue.cpp b/ACE/examples/APG/Threads/Message_Queue.cpp new file mode 100644 index 00000000000..3544d6bcefa --- /dev/null +++ b/ACE/examples/APG/Threads/Message_Queue.cpp @@ -0,0 +1,179 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/SOCK_Acceptor.h" +#include "ace/Acceptor.h" +#include "Message_Receiver.h" + +// Listing 5 code/ch12 +int +HA_CommandHandler::svc (void) +{ + while(1) + { + ACE_Message_Block *mb; + if (this->getq (mb) == -1) + break; + if (mb->msg_type () == ACE_Message_Block::MB_HANGUP) + { + mb->release (); + break; + } + else + { + // Get header pointer, then move past header to payload. + DeviceCommandHeader *dch + = (DeviceCommandHeader*)mb->rd_ptr (); + mb->rd_ptr (sizeof (DeviceCommandHeader)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Message for device #%d with ") + ACE_TEXT ("command payload of:\n%s"), + dch->deviceId_, mb->rd_ptr ())); + this->rep_.update_device (dch->deviceId_, + mb->rd_ptr ()); + mb->release (); + } + } + + ACE_Reactor::instance ()->end_reactor_event_loop (); + + return 0; +} +// Listing 5 + +// Listing 4 code/ch12 +ACE_Message_Block * +Message_Receiver::shut_down_message (void) +{ + ACE_Message_Block *mb; + ACE_NEW_RETURN + (mb, ACE_Message_Block (0, ACE_Message_Block::MB_HANGUP), 0); + return mb; +} +// Listing 4 + +int +Message_Receiver::read_header (DeviceCommandHeader *dch) +{ + ssize_t result = + this->peer ().recv_n (dch, sizeof (DeviceCommandHeader)); + if (result <= 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Recieve Failure")), + -1); + return 0; +} +// Listing 3 code/ch12 +int +Message_Receiver::copy_payload (ACE_Message_Block *mb, + int payload_length) +{ + ssize_t result = + this->peer ().recv_n (mb->wr_ptr (), payload_length); + + if (result <= 0) + { + mb->release (); + return -1; + } + + mb->wr_ptr (payload_length); + return 0; +} +// Listing 3 +// Listing 2 code/ch12 +int +Message_Receiver::handle_input (ACE_HANDLE) +{ + DeviceCommandHeader dch; + if (this->read_header (&dch) < 0) + return -1; + + if (dch.deviceId_ < 0) + { + // Handle shutdown. + this->handler_->putq (shut_down_message ()); + return -1; + } + + ACE_Message_Block *mb; + ACE_NEW_RETURN + (mb, ACE_Message_Block (dch.length_ + sizeof dch), -1); + // Copy the header. + mb->copy ((const char*)&dch, sizeof dch); + // Copy the payload. + if (this->copy_payload (mb, dch.length_) < 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Recieve Failure")), -1); + // Pass it off to the handler thread. + this->handler_->putq (mb); + return 0; +} +// Listing 2 + +static void report_usage (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + { + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("%s port\n"), argv[1])); + ACE_OS::exit (-1); + } +} + + +class Acceptor : public ACE_Acceptor<Message_Receiver, ACE_SOCK_ACCEPTOR> +{ +public: + Acceptor(HA_CommandHandler *handler) : handler_(handler) + { } + +protected: + virtual int make_svc_handler (Message_Receiver *&mr) + { + ACE_NEW_RETURN (mr, Message_Receiver (handler_), -1); + return 0; + } + +private: + HA_CommandHandler *handler_; +}; + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + report_usage (argc, argv); + + u_short port = ACE_OS::atoi (argv[1]); + + HA_Device_Repository rep; + HA_CommandHandler handler (rep); + ACE_ASSERT(handler.activate()==0); + //start up the handler. + + Acceptor acceptor (&handler); + ACE_INET_Addr addr (port); + if (acceptor.open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Failed to open connection")), -1); + + ACE_Reactor::instance()->run_reactor_event_loop (); + //run the reactive event loop + + handler.wait (); + //reap the handler before exiting. + + return 0; +} + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Threads/Message_Receiver.h b/ACE/examples/APG/Threads/Message_Receiver.h new file mode 100644 index 00000000000..dee0731f007 --- /dev/null +++ b/ACE/examples/APG/Threads/Message_Receiver.h @@ -0,0 +1,90 @@ +/** + * $Id$ + * + * Sample code from The ACE Programmer's Guide, + * copyright 2003 Addison-Wesley. All Rights Reserved. + */ + +#ifndef __MESSAGE_RECEIVER_H_ +#define __MESSAGE_RECEIVER_H_ + +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" +#include "ace/Synch.h" +#include "ace/Task.h" + +// Listing 1 code/ch12 +struct DeviceCommandHeader +{ + int length_; + int deviceId_; +}; +// Listing 1 + +class HA_Device_Repository +{ +public: + HA_Device_Repository (); + + int update_device (int device_id, char *commands); + +private: + ACE_Task_Base *owner_; +}; + +HA_Device_Repository::HA_Device_Repository () +{ } + +int +HA_Device_Repository::update_device (int, char *) +{ + return 0; +} + +class HA_CommandHandler : public ACE_Task<ACE_MT_SYNCH> +{ +public: + HA_CommandHandler (HA_Device_Repository &rep) : rep_(rep) + { } + + virtual int svc(); + +private: + HA_Device_Repository &rep_; +}; + +class Message_Receiver : + public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> +{ +public: + Message_Receiver () : handler_(0) + { + ACE_ASSERT(0); + } + + Message_Receiver (HA_CommandHandler *ch) : handler_(ch) + { } + + ACE_Message_Block *shut_down_message (void); + + virtual int handle_input (ACE_HANDLE fd); + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) + { + this->peer ().close (); + delete this; + return 0; + } + +private: + int read_header (DeviceCommandHeader *dch); + int copy_payload (ACE_Message_Block *mb, int payload_length); + +private: + HA_CommandHandler *handler_; +}; + +#endif /* __MESSAGE_RECEIVER_H */ diff --git a/ACE/examples/APG/Threads/Mutexes.cpp b/ACE/examples/APG/Threads/Mutexes.cpp new file mode 100644 index 00000000000..ca5ebcdcbe4 --- /dev/null +++ b/ACE/examples/APG/Threads/Mutexes.cpp @@ -0,0 +1,75 @@ +// $Id$ + +#include "ace/config-lite.h" +#if defined (ACE_HAS_THREADS) + +#include "ace/Synch.h" +#include "ace/Task.h" + +// Listing 1 code/ch12 +class HA_Device_Repository +{ +public: + HA_Device_Repository () + { } + + void update_device (int device_id) + { + mutex_.acquire (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Updating device %d\n"), + device_id)); + ACE_OS::sleep (1); + mutex_.release (); + } + +private: + ACE_Thread_Mutex mutex_; +}; +// Listing 1 +// Listing 2 code/ch12 +class HA_CommandHandler : public ACE_Task_Base +{ +public: + enum {NUM_USES = 10}; + + HA_CommandHandler (HA_Device_Repository& rep) : rep_(rep) + { } + + virtual int svc (void) + { + ACE_DEBUG + ((LM_DEBUG, ACE_TEXT ("(%t) Handler Thread running\n"))); + for (int i=0; i < NUM_USES; i++) + this->rep_.update_device (i); + return 0; + } + +private: + HA_Device_Repository & rep_; +}; + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + HA_Device_Repository rep; + HA_CommandHandler handler1 (rep); + HA_CommandHandler handler2 (rep); + handler1.activate (); + handler2.activate (); + + handler1.wait (); + handler2.wait (); + return 0; +} +// Listing 2 + +#else +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::puts (ACE_TEXT ("This example requires threads.")); + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/APG/Threads/threads.mpc b/ACE/examples/APG/Threads/threads.mpc new file mode 100644 index 00000000000..a980a867d26 --- /dev/null +++ b/ACE/examples/APG/Threads/threads.mpc @@ -0,0 +1,44 @@ +// -*- MPC -*- +// $Id$ + +project(Activate) : aceexe { + exename = Activate + Source_Files { + Activate.cpp + } +} + +project(Condition Variables) : aceexe { + exename = Condition_Variables + Source_Files { + Condition_Variables.cpp + } +} + +project(Guards) : aceexe { + exename = Guards + Source_Files { + Guards.cpp + } +} + +project(Message Blocks) : aceexe { + exename = Message_Blocks + Source_Files { + Message_Blocks.cpp + } +} + +project(Message Queue) : aceexe { + exename = Message_Queue + Source_Files { + Message_Queue.cpp + } +} + +project(Mutexes) : aceexe { + exename = Mutexes + Source_Files { + Mutexes.cpp + } +} diff --git a/ACE/examples/APG/Timers/.cvsignore b/ACE/examples/APG/Timers/.cvsignore new file mode 100644 index 00000000000..9137f2e897a --- /dev/null +++ b/ACE/examples/APG/Timers/.cvsignore @@ -0,0 +1,8 @@ +Alarm +Alarm +Task +Task +Timers +Timers +Upcall +Upcall diff --git a/ACE/examples/APG/Timers/Alarm.cpp b/ACE/examples/APG/Timers/Alarm.cpp new file mode 100644 index 00000000000..c12d39b367d --- /dev/null +++ b/ACE/examples/APG/Timers/Alarm.cpp @@ -0,0 +1,57 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_time.h" + +// Listing 1 code/ch20 +#include "ace/Timer_Queue_Adapters.h" +#include "ace/Timer_Heap.h" + +typedef ACE_Async_Timer_Queue_Adapter<ACE_Timer_Heap> Timer; +// Listing 1 + +class CB : public ACE_Event_Handler +{ +public: + CB (int id) : id_(id) { } + + virtual int handle_timeout (const ACE_Time_Value &, + const void *arg) + { + ACE_TRACE (ACE_TEXT ("CB::handle_timeout")); + + const int *val = static_cast<const int*> (arg); + ACE_ASSERT ((*val) == id_); + + ACE_UNUSED_ARG (val); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Timer expired\n"))); + return 0; + } + +private: + int id_; +}; + +// Listing 2 code/ch20 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Create the timer such that it blocks all signals + // when it goes off. + Timer timer; + + // Schedule a timer to go off 2 seconds later and then + // after every 4 seconds. + CB cb (1); + int arg = 1; + ACE_Time_Value initial (2); + ACE_Time_Value repeat (4); + initial += ACE_OS::gettimeofday (); + timer.schedule (&cb, &arg, initial, repeat); + + while (1) // Don't let the main thread exit. + ACE_OS::sleep (2); + ACE_NOTREACHED (return 0); // Not reached. +} +// Listing 2 + diff --git a/ACE/examples/APG/Timers/CB.cpp b/ACE/examples/APG/Timers/CB.cpp new file mode 100644 index 00000000000..0a86ae7edeb --- /dev/null +++ b/ACE/examples/APG/Timers/CB.cpp @@ -0,0 +1,70 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "CB.h" +#include "TimerDispatcher.h" + +CB::CB () : count_(0) +{ + ACE_TRACE (ACE_TEXT ("CB::CB")); +} + +// Listing 1 code/ch20 +int CB::handle_timeout (const ACE_Time_Value &, + const void *arg) +{ + ACE_TRACE (ACE_TEXT ("CB::handle_timeout")); + + const int *val = static_cast<const int*> (arg); + ACE_ASSERT ((*val) == timerID_); + + ACE_UNUSED_ARG (val); + + if (count_ == 5) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Reseting interval for timer %d\n"), + timerID_)); + + // New interval is 10 ms. + ACE_Time_Value interval (0L, 1000L); + int status = Timer::instance ()->reset_interval + (timerID_, interval); +#if defined (ACE_NDEBUG) + ACE_UNUSED_ARG (status); +#else + ACE_ASSERT (status != -1); +#endif + } + + if (count_++ == 10) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Canceling %d\n"), + timerID_)); + ACE_ASSERT ((Timer::instance ()->cancel (this)) != 0); + } + + return 0; +} +// Listing 1 + +void +CB::setID (long timerID) +{ + ACE_TRACE (ACE_TEXT ("CB::setID")); + timerID_ = timerID; +} + +long +CB::getID (void) +{ + ACE_TRACE (ACE_TEXT ("CB::getID")); + return timerID_; +} + +int +CB::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE (ACE_TEXT ("CB::handle_close")); + return 0; +} diff --git a/ACE/examples/APG/Timers/CB.h b/ACE/examples/APG/Timers/CB.h new file mode 100644 index 00000000000..716ad4e4f50 --- /dev/null +++ b/ACE/examples/APG/Timers/CB.h @@ -0,0 +1,36 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(CB_H) +#define CB_H + +#include "ace/Event_Handler.h" + +#include "TimerDispatcher.h" + +// Listing 1 code/ch20 +class CB : public ACE_Event_Handler +{ +public: + CB (); + + // Set the timer id that is being handled by this instance. + void setID (long timerID); + + // Get the timer id. + long getID (void); + + // Handle the timeout. + virtual int handle_timeout(const ACE_Time_Value &tv, + const void *arg = 0); + + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); + +private: + long timerID_; + int count_; +}; +// Listing 1 + +#endif /*CB_H*/ diff --git a/ACE/examples/APG/Timers/Makefile.am b/ACE/examples/APG/Timers/Makefile.am new file mode 100644 index 00000000000..33976800fec --- /dev/null +++ b/ACE/examples/APG/Timers/Makefile.am @@ -0,0 +1,91 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.Alarm.am +noinst_PROGRAMS = Alarm + +Alarm_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Alarm_SOURCES = \ + Alarm.cpp \ + CB.h \ + PCB.h \ + PTimerDispatcher.h \ + TimerDispatcher.h \ + Upcall.h + +Alarm_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Task.am +noinst_PROGRAMS += Task + +Task_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Task_SOURCES = \ + Task.cpp \ + CB.h \ + PCB.h \ + PTimerDispatcher.h \ + TimerDispatcher.h \ + Upcall.h + +Task_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Timers.am +noinst_PROGRAMS += Timers + +Timers_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Timers_SOURCES = \ + CB.cpp \ + TimerDispatcher.cpp \ + Timers.cpp \ + CB.h \ + TimerDispatcher.h + +Timers_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Upcall.am +noinst_PROGRAMS += Upcall + +Upcall_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Upcall_SOURCES = \ + PCB.cpp \ + PTimerDispatcher.cpp \ + Upcall.cpp \ + PCB.h \ + PTimerDispatcher.h \ + Upcall.h + +Upcall_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Timers/PCB.cpp b/ACE/examples/APG/Timers/PCB.cpp new file mode 100644 index 00000000000..d3401c65116 --- /dev/null +++ b/ACE/examples/APG/Timers/PCB.cpp @@ -0,0 +1,79 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "PCB.h" +#include "PTimerDispatcher.h" + +PCB::PCB() : count_(0) +{ + ACE_TRACE (ACE_TEXT ("PCB::PCB")); +} + +PCB::~PCB() +{ +} + +int PCB::handleEvent (const void *arg) +{ + ACE_TRACE (ACE_TEXT ("PCB::handle_timeout")); + + const int *val = static_cast<const int*> (arg); + ACE_ASSERT ((*val) == timerID_); + + ACE_UNUSED_ARG (val); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("Timer %d expiry handled by thread %t\n"), + timerID_)); + if (count_ == 5) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Reseting interval for timer %d\n"), + timerID_)); + + // New interval is 10 ms. + ACE_Time_Value interval (0L, 1000L); + if (PTimer::instance ()->reset_interval (timerID_, interval) != -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("reset_interval")), + -1); + } + + if (count_++ == 10) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Canceling %d\n"), + timerID_)); + PTimer::instance ()->cancel (this); + } + + return 0; +} + +void +PCB::setID (long timerID) +{ + ACE_TRACE (ACE_TEXT ("PCB::setID")); + timerID_ = timerID; +} + +long +PCB::getID (void) const +{ + ACE_TRACE (ACE_TEXT ("PCB::getID")); + return timerID_; +} + +int +PCB::handleClose (void) +{ + ACE_TRACE (ACE_TEXT ("PCB::handle_close")); + return 0; +} + +int +PCB::handleCancel (void) +{ + ACE_TRACE (ACE_TEXT ("PCB::handleCancel")); + return 0; +} diff --git a/ACE/examples/APG/Timers/PCB.h b/ACE/examples/APG/Timers/PCB.h new file mode 100644 index 00000000000..7fdb9d2d1cf --- /dev/null +++ b/ACE/examples/APG/Timers/PCB.h @@ -0,0 +1,29 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(PCB_H) +#define PCB_H + +// Listing 1 code/ch20 +class PCB +{ +public: + PCB (); + virtual ~PCB (); + + // Set/get the timer id that is being handled by this instance. + void setID (long timerID); + long getID (void) const; + + // Handle a timeout event, cancel, and close. + virtual int handleEvent (const void *arg); + virtual int handleCancel (void); + virtual int handleClose (void); + +private: + long timerID_; + int count_; +}; +// Listing 1 + +#endif /*PCB_H*/ diff --git a/ACE/examples/APG/Timers/PTimerDispatcher.cpp b/ACE/examples/APG/Timers/PTimerDispatcher.cpp new file mode 100644 index 00000000000..405c5771789 --- /dev/null +++ b/ACE/examples/APG/Timers/PTimerDispatcher.cpp @@ -0,0 +1,69 @@ +// $Id$ + +#include "PTimerDispatcher.h" + +void PTimer_Dispatcher::wait_for_event (void) +{ + ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::wait_for_event")); + + while (1) + { + ACE_Time_Value max_tv = timer_queue_->gettimeofday (); + + ACE_Time_Value *this_timeout = + this->timer_queue_->calculate_timeout (&max_tv); + + if (*this_timeout == ACE_Time_Value::zero) + this->timer_queue_->expire (); + else + { + // Convert to absolute time. + ACE_Time_Value next_timeout = + timer_queue_->gettimeofday (); + next_timeout += *this_timeout; + if (this->timer_.wait (&next_timeout) == -1 ) + this->timer_queue_->expire (); + } + } +} + +long +PTimer_Dispatcher::schedule (PCB *cb, + void *arg, + const ACE_Time_Value &abs_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::schedule_timer")); + + return this->timer_queue_->schedule + (cb, arg, abs_time, interval); +} + +int +PTimer_Dispatcher::cancel (PCB *cb, + int dont_call_handle_close) +{ + ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::cancel")); + return timer_queue_->cancel (cb, dont_call_handle_close); +} + +void PTimer_Dispatcher::set (PTimerQueue *timer_queue) +{ + ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::set")); + + timer_queue_ = timer_queue; +} + +int +PTimer_Dispatcher::reset_interval (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::reset_interval")); + + return timer_queue_->reset_interval (timer_id, interval); +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<PTimer_Dispatcher, ACE_Null_Mutex> * + ACE_Singleton<PTimer_Dispatcher, ACE_Null_Mutex>::singleton_; +# endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ diff --git a/ACE/examples/APG/Timers/PTimerDispatcher.h b/ACE/examples/APG/Timers/PTimerDispatcher.h new file mode 100644 index 00000000000..8a530f41709 --- /dev/null +++ b/ACE/examples/APG/Timers/PTimerDispatcher.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(PTIMER_DISPATCHER_H) +#define PTIMER_DISPATCHER_H + +#include "ace/Singleton.h" +#include "ace/Synch.h" // needed for ACE_Event + +#include "Upcall.h" +class PCB; + +class PTimer_Dispatcher +{ +public: + void wait_for_event (void); + + long schedule (PCB *cb, + void *arg, + const ACE_Time_Value &abs_time, + const ACE_Time_Value &interval); + + int cancel (PCB *cb, + int dont_call_handle_close = 1); + + int reset_interval (long timer_id, + const ACE_Time_Value &interval); + + void set (PTimerQueue *timer_queue); + +private: + PTimerQueue *timer_queue_; + ACE_Event timer_; +}; + +typedef ACE_Singleton<PTimer_Dispatcher, ACE_Null_Mutex> PTimer; + +#endif /*TIMER_DISPATCHER_H*/ + diff --git a/ACE/examples/APG/Timers/Task.cpp b/ACE/examples/APG/Timers/Task.cpp new file mode 100644 index 00000000000..4774eb1444f --- /dev/null +++ b/ACE/examples/APG/Timers/Task.cpp @@ -0,0 +1,73 @@ +// $Id$ + +#include "ace/OS_NS_sys_time.h" + +// Listing 1 code/ch20 +#include "ace/Timer_Queue_Adapters.h" +#include "ace/Timer_Heap.h" + +typedef ACE_Thread_Timer_Queue_Adapter<ACE_Timer_Heap> + ActiveTimer; + +// Listing 1 +// Listing 2 code/ch20 +class CB : public ACE_Event_Handler +{ +public: + CB (int id) : id_(id) { } + + virtual int handle_timeout (const ACE_Time_Value &, + const void *arg) + { + ACE_TRACE (ACE_TEXT ("CB::handle_timeout")); + + const int *val = static_cast<const int*> (arg); + ACE_ASSERT((*val) == id_); + + ACE_UNUSED_ARG (val); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Expiry handled by thread %t\n"))); + return 0; + } + +private: + int id_; +}; +// Listing 2 + +// Listing 3 code/ch20 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("the main thread %t has started \n"))); + + // Create an "active" timer and start its thread. + ActiveTimer atimer; + atimer.activate (); + + CB cb1 (1); + CB cb2 (2); + int arg1 = 1; + int arg2 = 2; + + // Schedule timers to go off 3 & 4 seconds from now + // and then with an interval of 1.1 seconds. + const ACE_Time_Value curr_tv = ACE_OS::gettimeofday (); + ACE_Time_Value interval = ACE_Time_Value (1, 100000); + + atimer.schedule (&cb1, + &arg1, + curr_tv + ACE_Time_Value (3L), + interval); + atimer.schedule (&cb2, + &arg2, + curr_tv + ACE_Time_Value (4L), + interval); + + ACE_Thread_Manager::instance ()->wait (); // Wait forever. + + return 0; +} +// Listing 3 + diff --git a/ACE/examples/APG/Timers/TimerDispatcher.cpp b/ACE/examples/APG/Timers/TimerDispatcher.cpp new file mode 100644 index 00000000000..818d762b738 --- /dev/null +++ b/ACE/examples/APG/Timers/TimerDispatcher.cpp @@ -0,0 +1,73 @@ +// $Id$ + +#include "TimerDispatcher.h" +// Listing 1 code/ch20 +void Timer_Dispatcher::wait_for_event (void) +{ + ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::wait_for_event")); + + while (1) + { + ACE_Time_Value max_tv = timer_queue_->gettimeofday (); + + ACE_Time_Value *this_timeout = + this->timer_queue_->calculate_timeout (&max_tv); + + if (*this_timeout == ACE_Time_Value::zero) + this->timer_queue_->expire (); + else + { + // Convert to absolute time. + ACE_Time_Value next_timeout = + timer_queue_->gettimeofday (); + next_timeout += *this_timeout; + if (this->timer_.wait (&next_timeout) == -1 ) + this->timer_queue_->expire (); + } + } +} +// Listing 1 +// Listing 2 code/ch20 +long +Timer_Dispatcher::schedule (ACE_Event_Handler *cb, + void *arg, + const ACE_Time_Value &abs_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::schedule_timer")); + + return this->timer_queue_->schedule + (cb, arg, abs_time, interval); +} +// Listing 2 +// Listing 3 code/ch20 +int +Timer_Dispatcher::cancel (ACE_Event_Handler *cb, + int dont_call_handle_close) +{ + ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::cancel")); + return timer_queue_->cancel (cb, dont_call_handle_close); +} +// Listing 3 +// Listing 4 code/ch20 +void Timer_Dispatcher::set (ACE_Timer_Queue *timer_queue) +{ + ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::set")); + + timer_queue_ = timer_queue; +} +// Listing 4 + +int +Timer_Dispatcher::reset_interval (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::reset_interval")); + + return timer_queue_->reset_interval(timer_id, interval); +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<Timer_Dispatcher, ACE_Null_Mutex> * + ACE_Singleton<Timer_Dispatcher, ACE_Null_Mutex>::singleton_; +# endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ diff --git a/ACE/examples/APG/Timers/TimerDispatcher.h b/ACE/examples/APG/Timers/TimerDispatcher.h new file mode 100644 index 00000000000..fc519b77615 --- /dev/null +++ b/ACE/examples/APG/Timers/TimerDispatcher.h @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(TIMER_DISPATCHER_H) +#define TIMER_DISPATCHER_H + +#include "ace/Event_Handler.h" +#include "ace/Singleton.h" +#include "ace/Synch.h" // needed for ACE_Event +#include "ace/Timer_Queue.h" + +// Listing 1 code/ch20 +class Timer_Dispatcher +{ +public: + void wait_for_event (void); + + long schedule (ACE_Event_Handler *cb, + void *arg, + const ACE_Time_Value &abs_time, + const ACE_Time_Value &interval); + + int cancel (ACE_Event_Handler *cb, + int dont_call_handle_close = 1); + + int reset_interval (long timer_id, + const ACE_Time_Value &interval); + + void set (ACE_Timer_Queue *timer_queue); + +private: + ACE_Timer_Queue *timer_queue_; + ACE_Event timer_; +}; + +typedef ACE_Singleton<Timer_Dispatcher, ACE_Null_Mutex> Timer; +// Listing 1 + +#endif /*TIMER_DISPATCHER_H*/ + diff --git a/ACE/examples/APG/Timers/Timers.cpp b/ACE/examples/APG/Timers/Timers.cpp new file mode 100644 index 00000000000..761f03a650c --- /dev/null +++ b/ACE/examples/APG/Timers/Timers.cpp @@ -0,0 +1,58 @@ +// $Id$ + +// Listing 1 code/ch20 +#include "ace/Timer_Queue.h" +#include "ace/Timer_Heap.h" +#include "ace/Timer_Wheel.h" +#include "ace/Timer_Hash.h" +#include "ace/Timer_List.h" + +#include "CB.h" +#include "TimerDispatcher.h" + +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_Timer_Queue *timer_queue; + +#if defined(HEAP) + + ACE_NEW_RETURN (timer_queue, ACE_Timer_Heap, -1); +#elsif defined(HASH) + + ACE_NEW_RETURN (timer_queue, ACE_Timer_Hash, -1); +#elsif defined(WHEEL) + + ACE_NEW_RETURN (timer_queue, ACE_Timer_Wheel, -1); +#else + + ACE_NEW_RETURN (timer_queue, ACE_Timer_List, -1); +#endif + + // setup the timer queue + Timer::instance ()->set (timer_queue); + + CB cb[10]; + long args[10]; + for (long i = 0; i < 10 ; i++) + { + ACE_Time_Value const timeout (i); + long timerID = + Timer::instance ()->schedule + (&cb[i], + &args[i], + timer_queue->gettimeofday () + (ACE_Time_Value)5, + timeout); + + // Set the timerID state variable of the handler. + cb[i].setID (timerID); + + // Implicitly send the handler it's timer id. + args[i] = timerID; + } + + // "run" the timer. + Timer::instance ()->wait_for_event (); + + return 0; +} +// Listing 1 diff --git a/ACE/examples/APG/Timers/Upcall.cpp b/ACE/examples/APG/Timers/Upcall.cpp new file mode 100644 index 00000000000..cb00ae6113a --- /dev/null +++ b/ACE/examples/APG/Timers/Upcall.cpp @@ -0,0 +1,172 @@ +// $Id$ + +#include "ace/OS_NS_sys_time.h" +#include "ace/Log_Msg.h" +#include "Upcall.h" +#include "PTimerDispatcher.h" + +// Listing 2 code/ch20 +// The signature of this method changed at ACE 5.4. The 'recurring_timer' +// parameter was added. +int +UpcallHandler::timeout (PTimerQueue &, + PCB *handler, + const void *arg, + int /* recurring_timer */, + const ACE_Time_Value &) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::timeout")); + + return (*handler).handleEvent (arg); +} + +#if 0 +// This method was removed at ACE 5.4. Replaced by cancel_type() and +// cancel_timer(). +int +UpcallHandler::cancellation (PTimerQueue &, + PCB *handler) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::cancellation")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d has been cancelled\n"), + handler->getID ())); + + return handler->handleCancel (); +} +#endif /* 0 */ + +// This method is called when the timer is canceled +int +UpcallHandler::deletion (PTimerQueue &, + PCB *handler, + const void *) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::deletion")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d has been deleted\n"), + handler->getID ())); + + return handler->handleClose (); +} +// Listing 2 + +// *** The rest of the UpcallHandler methods were added for ACE 5.4 *** + +// This method is called when a timer is registered. +int +UpcallHandler::registration (PTimerQueue &, + PCB *handler, + const void *) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::registration")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d has been registered.\n"), + handler->getID ())); + return 0; +} + +// This method is called at expiration time, before the actual upcall +// to the handler is made. ACE uses this to adjust reference counts +// when needed. +int +UpcallHandler::preinvoke (PTimerQueue &, + PCB *handler, + const void *, + int, + const ACE_Time_Value &, + const void *&) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::preinvoke")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d is about to upcalled.\n"), + handler->getID ())); + return 0; +} + +// This method is called at expiration time, after the actual upcall +// to the handler returns. ACE uses this to adjust reference counts +// when needed. +int +UpcallHandler::postinvoke (PTimerQueue &, + PCB *handler, + const void *, + int, + const ACE_Time_Value &, + const void *) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::postinvoke")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d returned from upcall.\n"), + handler->getID ())); + return 0; +} + +// This method is called when a handler is cancelled +int +UpcallHandler::cancel_type (PTimerQueue &, + PCB *handler, + int dont_call, + int &) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::cancel_type")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d has been cancelled\n"), + handler->getID ())); + if (!dont_call) + return handler->handleCancel (); + return 0; +} + +// This method is called when a timer is cancelled +int +UpcallHandler::cancel_timer (PTimerQueue &, + PCB *handler, + int dont_call, + int) +{ + ACE_TRACE (ACE_TEXT ("UpcallHandler::cancel_timer")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Handler %d has been cancelled\n"), + handler->getID ())); + if (!dont_call) + return handler->handleCancel (); + return 0; +} + + +// Listing 3 code/ch20 +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + PCB cb1, cb2; + cb1.setID (1); + cb2.setID (2); + int arg1 = 1, arg2 = 2; + + PTimerQueue *timerQueue; + + ACE_NEW_RETURN (timerQueue, PTimerHeap (), -1); + + PTimer::instance ()->set (timerQueue); + + ACE_Time_Value tv = ACE_OS::gettimeofday (); + tv += 20L; + + // Schedule two different timers to go off. + PTimer::instance ()->schedule (&cb1, &arg1, tv, ACE_Time_Value (1)); + PTimer::instance ()->schedule (&cb2, &arg2, tv, ACE_Time_Value (2)); + + // Run the timer event loop forever. + PTimer::instance ()->wait_for_event (); + + return 0; +} +// Listing 3 + diff --git a/ACE/examples/APG/Timers/Upcall.h b/ACE/examples/APG/Timers/Upcall.h new file mode 100644 index 00000000000..6a154f3b8b1 --- /dev/null +++ b/ACE/examples/APG/Timers/Upcall.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined(UPCALL_H) +#define UPCALL_H + +#include "ace/Timer_Queue_T.h" +#include "ace/Timer_Heap_T.h" +#include "ace/Synch.h" + +#include "PCB.h" + +// Listing 1 code/ch20 +class UpcallHandler; + +typedef ACE_Timer_Queue_T<PCB*, UpcallHandler, ACE_Null_Mutex> + PTimerQueue; + +// Create a special heap-based timer queue that allows you to +// control exactly how timer evetns are handled. +typedef ACE_Timer_Heap_T<PCB*, UpcallHandler, ACE_Null_Mutex> + PTimerHeap; +// Listing 1 + +class UpcallHandler +{ +public: + // The signature of this method changed at ACE 5.4. The 'recurring_timer' + // parameter was added. + int timeout (PTimerQueue &timer_queue, + PCB *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time); + +#if 0 + // This method was removed at ACE 5.4. Replaced by cancel_type() and + // cancel_timer(). + // This method is called when the timer is canceled. + int cancellation (PTimerQueue &timer_queue, + PCB *handler); +#endif + + // This method is called when the timer queue is destroyed and + // the timer is still contained in it. + int deletion (PTimerQueue &timer_queue, + PCB *handler, + const void *arg); + + // The following methods don't appear before ACE 5.4, so aren't + // referenced in APG (it's based on ACE 5.3). + + // This method is called when a timer is registered. + int registration (PTimerQueue &timer_queue, + PCB *handler, + const void *arg); + + // This method is called before the timer expires. + int preinvoke (PTimerQueue &timer_queue, + PCB *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *&upcall_act); + + // This method is called after the timer expires. + int postinvoke (PTimerQueue &timer_queue, + PCB *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *upcall_act); + + // This method is called when a handler is cancelled + int cancel_type (PTimerQueue &timer_queue, + PCB *handler, + int dont_call, + int &requires_reference_counting); + + // This method is called when a timer is cancelled + int cancel_timer (PTimerQueue &timer_queue, + PCB *handler, + int dont_call, + int requires_reference_counting); +}; + +#endif /*UPCALL_H*/ diff --git a/ACE/examples/APG/Timers/timers.mpc b/ACE/examples/APG/Timers/timers.mpc new file mode 100644 index 00000000000..295b2bb97d5 --- /dev/null +++ b/ACE/examples/APG/Timers/timers.mpc @@ -0,0 +1,34 @@ +// -*- MPC -*- +// $Id$ + +project(Alarm) : aceexe { + exename = Alarm + Source_Files { + Alarm.cpp + } +} + +project(Task) : aceexe { + exename = Task + Source_Files { + Task.cpp + } +} + +project(Timers) : aceexe { + exename = Timers + Source_Files { + Timers.cpp + CB.cpp + TimerDispatcher.cpp + } +} + +project(Upcall) : aceexe { + exename = Upcall + Source_Files { + Upcall.cpp + PCB.cpp + PTimerDispatcher.cpp + } +} |