summaryrefslogtreecommitdiff
path: root/examples/APG
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2004-01-01 21:01:01 +0000
committerSteve Huston <shuston@riverace.com>2004-01-01 21:01:01 +0000
commit6649a1a542c18bd756757a2d58f3ea51eea0cc47 (patch)
tree15b88279a4187c88c37adabba8740a0165139299 /examples/APG
parentfcf24b2de58a080db0617c641f337298614a944b (diff)
downloadATCD-6649a1a542c18bd756757a2d58f3ea51eea0cc47.tar.gz
ChangeLogTag:Thu Jan 1 15:20:30 2004 Steve Huston <shuston@riverace.com>
Diffstat (limited to 'examples/APG')
-rw-r--r--examples/APG/Active_Objects/AO.cpp188
-rw-r--r--examples/APG/Active_Objects/AO2.cpp197
-rw-r--r--examples/APG/Active_Objects/Makefile15
-rw-r--r--examples/APG/Active_Objects/active_objects.mpc13
-rw-r--r--examples/APG/Active_Objects/active_objects.mwc3
-rw-r--r--examples/APG/Config/ARGV_Example.cpp60
-rw-r--r--examples/APG/Config/Get_Opt.cpp58
-rw-r--r--examples/APG/Config/Get_Opt_Long.cpp47
-rw-r--r--examples/APG/Config/HASTATUS_export.h50
-rw-r--r--examples/APG/Config/HA_Status.cpp93
-rw-r--r--examples/APG/Config/HA_Status.h85
-rw-r--r--examples/APG/Config/Makefile23
-rw-r--r--examples/APG/Config/config.mpc28
-rw-r--r--examples/APG/Config/config.mwc3
-rw-r--r--examples/APG/Containers/Allocator.cpp102
-rw-r--r--examples/APG/Containers/Array.cpp49
-rw-r--r--examples/APG/Containers/DLList.cpp128
-rw-r--r--examples/APG/Containers/DataElement.h52
-rw-r--r--examples/APG/Containers/Hash_Map.cpp134
-rw-r--r--examples/APG/Containers/Hash_Map_Hash.cpp129
-rw-r--r--examples/APG/Containers/Hash_Map_Hash.h52
-rw-r--r--examples/APG/Containers/KeyType.h28
-rw-r--r--examples/APG/Containers/Makefile30
-rw-r--r--examples/APG/Containers/Map_Manager.cpp135
-rw-r--r--examples/APG/Containers/Map_Manager_Specialization.cpp170
-rw-r--r--examples/APG/Containers/Queues.cpp129
-rw-r--r--examples/APG/Containers/RB_Tree.cpp158
-rw-r--r--examples/APG/Containers/RB_Tree_Functors.cpp156
-rw-r--r--examples/APG/Containers/RB_Tree_Functors.h32
-rw-r--r--examples/APG/Containers/Sets.cpp134
-rw-r--r--examples/APG/Containers/Stacks.cpp161
-rw-r--r--examples/APG/Containers/containers.mpc83
-rw-r--r--examples/APG/Containers/containers.mwc3
-rw-r--r--examples/APG/Logging/Callback-2.h38
-rw-r--r--examples/APG/Logging/Callback-3.h59
-rw-r--r--examples/APG/Logging/Callback.h15
-rw-r--r--examples/APG/Logging/Change_Instance_Default.cpp37
-rw-r--r--examples/APG/Logging/Change_Mask.cpp29
-rw-r--r--examples/APG/Logging/Howto_Syslog.cpp28
-rw-r--r--examples/APG/Logging/LogManager.h101
-rw-r--r--examples/APG/Logging/Log_Msg_Alt.h19
-rw-r--r--examples/APG/Logging/Makefile36
-rw-r--r--examples/APG/Logging/Simple1.cpp23
-rw-r--r--examples/APG/Logging/Simple2.cpp25
-rw-r--r--examples/APG/Logging/Trace.h151
-rw-r--r--examples/APG/Logging/Trace_Return.cpp39
-rw-r--r--examples/APG/Logging/Use_Callback.cpp20
-rw-r--r--examples/APG/Logging/Use_Callback2.cpp20
-rw-r--r--examples/APG/Logging/Use_LogManager.cpp37
-rw-r--r--examples/APG/Logging/Use_Logger.cpp17
-rw-r--r--examples/APG/Logging/Use_Logging_Server.cpp20
-rw-r--r--examples/APG/Logging/Use_Logging_Strategy.cpp33
-rw-r--r--examples/APG/Logging/Use_Multiple_Sinks.cpp34
-rw-r--r--examples/APG/Logging/Use_Ostream.cpp37
-rw-r--r--examples/APG/Logging/Use_Stderr.cpp39
-rw-r--r--examples/APG/Logging/Use_Syslog.cpp32
-rw-r--r--examples/APG/Logging/Wrap_Macros.cpp36
-rw-r--r--examples/APG/Logging/Wrap_Macros_Alt.cpp18
-rw-r--r--examples/APG/Logging/client.conf1
-rw-r--r--examples/APG/Logging/logging.mpc125
-rw-r--r--examples/APG/Logging/logging.mwc3
-rw-r--r--examples/APG/Logging/logging_strategy.conf1
-rw-r--r--examples/APG/Logging/server.conf3
-rw-r--r--examples/APG/Makefile40
-rw-r--r--examples/APG/Misc_IPC/Makefile14
-rw-r--r--examples/APG/Misc_IPC/UDP_Broadcast.cpp34
-rw-r--r--examples/APG/Misc_IPC/UDP_Multicast.cpp37
-rw-r--r--examples/APG/Misc_IPC/UDP_Unicast.cpp71
-rw-r--r--examples/APG/Misc_IPC/misc_ipc.mpc20
-rw-r--r--examples/APG/Misc_IPC/misc_ipc.mwc3
-rw-r--r--examples/APG/Naming/EMail.h28
-rw-r--r--examples/APG/Naming/Graph.cpp48
-rw-r--r--examples/APG/Naming/Graph.h18
-rw-r--r--examples/APG/Naming/Graphable_Element.cpp13
-rw-r--r--examples/APG/Naming/Graphable_Element.h53
-rw-r--r--examples/APG/Naming/Makefile39
-rw-r--r--examples/APG/Naming/Makefile.netlocal14
-rw-r--r--examples/APG/Naming/Makefile.netlocal_reader14
-rw-r--r--examples/APG/Naming/Makefile.nodelocal14
-rw-r--r--examples/APG/Naming/Makefile.nodelocal_shared14
-rw-r--r--examples/APG/Naming/Makefile.nodelocal_shared_reader17
-rw-r--r--examples/APG/Naming/Name_Binding.h58
-rw-r--r--examples/APG/Naming/Naming_Context.h67
-rw-r--r--examples/APG/Naming/Netlocal.cpp40
-rw-r--r--examples/APG/Naming/Netlocal_reader.cpp23
-rw-r--r--examples/APG/Naming/Nodelocal.cpp37
-rw-r--r--examples/APG/Naming/Nodelocal_shared.cpp43
-rw-r--r--examples/APG/Naming/Nodelocal_shared_reader.cpp23
-rw-r--r--examples/APG/Naming/Temperature_Grapher.cpp80
-rw-r--r--examples/APG/Naming/Temperature_Grapher.h30
-rw-r--r--examples/APG/Naming/Temperature_Grapher_Options.h21
-rw-r--r--examples/APG/Naming/Temperature_Monitor.cpp131
-rw-r--r--examples/APG/Naming/Temperature_Monitor.h29
-rw-r--r--examples/APG/Naming/Temperature_Monitor2.cpp142
-rw-r--r--examples/APG/Naming/Temperature_Monitor2.h35
-rw-r--r--examples/APG/Naming/Temperature_Monitor_Options.h48
-rw-r--r--examples/APG/Naming/Thermometer.h47
-rw-r--r--examples/APG/Naming/naming.mpc42
-rw-r--r--examples/APG/Naming/naming.mwc3
-rw-r--r--examples/APG/Naming/svc.conf1
-rw-r--r--examples/APG/Proactor/HA_Proactive_Status.cpp147
-rw-r--r--examples/APG/Proactor/HA_Proactive_Status.h81
-rw-r--r--examples/APG/Proactor/Makefile12
-rw-r--r--examples/APG/Proactor/proactor.mpc6
-rw-r--r--examples/APG/Proactor/proactor.mwc3
-rw-r--r--examples/APG/Processes/Makefile17
-rw-r--r--examples/APG/Processes/Process_Manager_Death.cpp66
-rw-r--r--examples/APG/Processes/Process_Manager_Spawn.cpp58
-rw-r--r--examples/APG/Processes/Process_Mutex.cpp78
-rw-r--r--examples/APG/Processes/Spawn.cpp197
-rw-r--r--examples/APG/Processes/processes.mpc27
-rw-r--r--examples/APG/Processes/processes.mwc3
-rw-r--r--examples/APG/Reactor/Client.cpp118
-rw-r--r--examples/APG/Reactor/Client.h48
-rw-r--r--examples/APG/Reactor/ClientService.h36
-rw-r--r--examples/APG/Reactor/HAStatus-AC.cpp144
-rw-r--r--examples/APG/Reactor/HAStatus.cpp326
-rw-r--r--examples/APG/Reactor/Makefile27
-rw-r--r--examples/APG/Reactor/Reschedule.cpp82
-rw-r--r--examples/APG/Reactor/Schedule_Timers.cpp64
-rw-r--r--examples/APG/Reactor/Timer_Cancel.cpp103
-rw-r--r--examples/APG/Reactor/Timer_State_Data.cpp152
-rw-r--r--examples/APG/Reactor/Timers.cpp79
-rw-r--r--examples/APG/Reactor/reactor.mpc55
-rw-r--r--examples/APG/Reactor/reactor.mwc3
-rw-r--r--examples/APG/Shared_Memory/Hash_Map.cpp257
-rw-r--r--examples/APG/Shared_Memory/Makefile21
-rw-r--r--examples/APG/Shared_Memory/Malloc.cpp124
-rw-r--r--examples/APG/Shared_Memory/Mem_Map.cpp34
-rw-r--r--examples/APG/Shared_Memory/PI_Malloc.cpp146
-rw-r--r--examples/APG/Shared_Memory/Pool_Growth.cpp269
-rw-r--r--examples/APG/Shared_Memory/Record.h45
-rw-r--r--examples/APG/Shared_Memory/shared_memory.mpc34
-rw-r--r--examples/APG/Shared_Memory/shared_memory.mwc3
-rw-r--r--examples/APG/Signals/Makefile18
-rw-r--r--examples/APG/Signals/SigAction.cpp68
-rw-r--r--examples/APG/Signals/SigGuard.cpp41
-rw-r--r--examples/APG/Signals/SigHandler.cpp58
-rw-r--r--examples/APG/Signals/SigHandlers.cpp52
-rw-r--r--examples/APG/Signals/SigInfo.cpp149
-rw-r--r--examples/APG/Signals/signals.mpc34
-rw-r--r--examples/APG/Signals/signals.mwc3
-rw-r--r--examples/APG/Sockets/Basic.cpp35
-rw-r--r--examples/APG/Sockets/Basic_Robust.cpp135
-rw-r--r--examples/APG/Sockets/Iovec.cpp84
-rw-r--r--examples/APG/Sockets/Makefile14
-rw-r--r--examples/APG/Sockets/Server.cpp92
-rw-r--r--examples/APG/Sockets/sockets.mpc27
-rw-r--r--examples/APG/Sockets/sockets.mwc3
-rw-r--r--examples/APG/Streams/Answerer.cpp411
-rw-r--r--examples/APG/Streams/BasicTask.h144
-rw-r--r--examples/APG/Streams/Command.h40
-rw-r--r--examples/APG/Streams/CommandModule.cpp20
-rw-r--r--examples/APG/Streams/CommandModule.h27
-rw-r--r--examples/APG/Streams/CommandStream.cpp91
-rw-r--r--examples/APG/Streams/CommandStream.h34
-rw-r--r--examples/APG/Streams/CommandTask.cpp153
-rw-r--r--examples/APG/Streams/CommandTask.h39
-rw-r--r--examples/APG/Streams/CommandTasks.cpp221
-rw-r--r--examples/APG/Streams/CommandTasks.h108
-rw-r--r--examples/APG/Streams/EndTask.h27
-rw-r--r--examples/APG/Streams/Makefile24
-rw-r--r--examples/APG/Streams/Message.h92
-rw-r--r--examples/APG/Streams/MessageInfo.h100
-rw-r--r--examples/APG/Streams/RecordingDevice.h118
-rw-r--r--examples/APG/Streams/RecordingDeviceFactory.cpp25
-rw-r--r--examples/APG/Streams/RecordingDeviceFactory.h22
-rw-r--r--examples/APG/Streams/RecordingDevice_QC.h5
-rw-r--r--examples/APG/Streams/RecordingDevice_Text.cpp200
-rw-r--r--examples/APG/Streams/RecordingDevice_Text.h84
-rw-r--r--examples/APG/Streams/RecordingDevice_USRVM.h5
-rw-r--r--examples/APG/Streams/Util.h92
-rw-r--r--examples/APG/Streams/streams.mpc12
-rw-r--r--examples/APG/Streams/streams.mwc3
-rw-r--r--examples/APG/Svc_Config/HASTATUS_export.h49
-rw-r--r--examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp14
-rw-r--r--examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp18
-rw-r--r--examples/APG/Svc_Config/HA_Status_Dynamic.cpp119
-rw-r--r--examples/APG/Svc_Config/HA_Status_Dynamic.h43
-rw-r--r--examples/APG/Svc_Config/HA_Status_Static.cpp127
-rw-r--r--examples/APG/Svc_Config/HA_Status_Static.h39
-rw-r--r--examples/APG/Svc_Config/Makefile35
-rw-r--r--examples/APG/Svc_Config/Makefile.dynamic20
-rw-r--r--examples/APG/Svc_Config/Makefile.static14
-rw-r--r--examples/APG/Svc_Config/status.ini2
-rw-r--r--examples/APG/Svc_Config/svc.conf.dynamic2
-rw-r--r--examples/APG/Svc_Config/svc.conf.static1
-rw-r--r--examples/APG/Svc_Config/svc_config.mpc22
-rw-r--r--examples/APG/Svc_Config/svc_config.mwc3
-rw-r--r--examples/APG/ThreadManagement/Async_Cancel.cpp69
-rw-r--r--examples/APG/ThreadManagement/Coop_Cancel.cpp51
-rw-r--r--examples/APG/ThreadManagement/ExitHandler.cpp71
-rw-r--r--examples/APG/ThreadManagement/Makefile29
-rw-r--r--examples/APG/ThreadManagement/Pool.cpp31
-rw-r--r--examples/APG/ThreadManagement/Priorities.cpp70
-rw-r--r--examples/APG/ThreadManagement/SecurityContext.h16
-rw-r--r--examples/APG/ThreadManagement/Signals.cpp80
-rw-r--r--examples/APG/ThreadManagement/Signals2.cpp85
-rw-r--r--examples/APG/ThreadManagement/Start_Hook.cpp59
-rw-r--r--examples/APG/ThreadManagement/State.cpp37
-rw-r--r--examples/APG/ThreadManagement/threadmgmt.mpc62
-rw-r--r--examples/APG/ThreadManagement/threadmgmt.mwc3
-rw-r--r--examples/APG/ThreadPools/Futures.cpp301
-rw-r--r--examples/APG/ThreadPools/LF_ThreadPool.cpp235
-rw-r--r--examples/APG/ThreadPools/Makefile25
-rw-r--r--examples/APG/ThreadPools/Request_Handler.h31
-rw-r--r--examples/APG/ThreadPools/TP_Reactor.cpp269
-rw-r--r--examples/APG/ThreadPools/Task_ThreadPool.cpp131
-rw-r--r--examples/APG/ThreadPools/ThreadPool.cpp252
-rw-r--r--examples/APG/ThreadPools/threadpools.mpc34
-rw-r--r--examples/APG/ThreadPools/threadpools.mwc3
-rw-r--r--examples/APG/ThreadSafety/Atomic_Op.cpp134
-rw-r--r--examples/APG/ThreadSafety/Barrier.cpp75
-rw-r--r--examples/APG/ThreadSafety/ClientContext.h30
-rw-r--r--examples/APG/ThreadSafety/Makefile28
-rw-r--r--examples/APG/ThreadSafety/Mutex.cpp54
-rw-r--r--examples/APG/ThreadSafety/RW_Lock.cpp124
-rw-r--r--examples/APG/ThreadSafety/Semaphore.cpp132
-rw-r--r--examples/APG/ThreadSafety/TSS.cpp61
-rw-r--r--examples/APG/ThreadSafety/Tokens.cpp101
-rw-r--r--examples/APG/ThreadSafety/Tokens_Deadlock.cpp68
-rw-r--r--examples/APG/ThreadSafety/threadsafety.mpc55
-rw-r--r--examples/APG/ThreadSafety/threadsafety.mwc3
-rw-r--r--examples/APG/Threads/Activate.cpp30
-rw-r--r--examples/APG/Threads/Condition_Variables.cpp105
-rw-r--r--examples/APG/Threads/Guards.cpp52
-rw-r--r--examples/APG/Threads/Makefile26
-rw-r--r--examples/APG/Threads/Message_Blocks.cpp40
-rw-r--r--examples/APG/Threads/Message_Queue.cpp164
-rw-r--r--examples/APG/Threads/Message_Receiver.h90
-rw-r--r--examples/APG/Threads/Mutexes.cpp61
-rw-r--r--examples/APG/Threads/threads.mpc41
-rw-r--r--examples/APG/Threads/threads.mwc3
-rw-r--r--examples/APG/Timers/Alarm.cpp51
-rw-r--r--examples/APG/Timers/CB.cpp62
-rw-r--r--examples/APG/Timers/CB.h36
-rw-r--r--examples/APG/Timers/Makefile36
-rw-r--r--examples/APG/Timers/Makefile.singles14
-rw-r--r--examples/APG/Timers/Makefile.timers14
-rw-r--r--examples/APG/Timers/Makefile.upcall14
-rw-r--r--examples/APG/Timers/PCB.cpp70
-rw-r--r--examples/APG/Timers/PCB.h28
-rw-r--r--examples/APG/Timers/PTimerDispatcher.cpp64
-rw-r--r--examples/APG/Timers/PTimerDispatcher.h39
-rw-r--r--examples/APG/Timers/Task.cpp69
-rw-r--r--examples/APG/Timers/TimerDispatcher.cpp68
-rw-r--r--examples/APG/Timers/TimerDispatcher.h40
-rw-r--r--examples/APG/Timers/Timers.cpp57
-rw-r--r--examples/APG/Timers/Upcall.cpp75
-rw-r--r--examples/APG/Timers/Upcall.h44
-rw-r--r--examples/APG/Timers/timers.mpc31
-rw-r--r--examples/APG/Timers/timers.mwc3
252 files changed, 15714 insertions, 0 deletions
diff --git a/examples/APG/Active_Objects/AO.cpp b/examples/APG/Active_Objects/AO.cpp
new file mode 100644
index 00000000000..f5bd6eb0a4e
--- /dev/null
+++ b/examples/APG/Active_Objects/AO.cpp
@@ -0,0 +1,188 @@
+// $Id$
+
+#include "ace/Activation_Queue.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;
+ 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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Future<int>;
+template class ACE_Future_Rep<int>;
+template class ACE_Future_Observer<int>;
+template class ACE_Unbounded_Set<ACE_Future_Observer<int> *>;
+template class ACE_Node<ACE_Future_Observer<int> *>;
+template class ACE_Unbounded_Set_Iterator<ACE_Future_Observer<int> *>;
+template class ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+pragma instantiate ACE_Future<int>;
+pragma instantiate ACE_Future_Rep<int>;
+pragma instantiate ACE_Future_Observer<int>;
+pragma instantiate ACE_Unbounded_Set<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Node<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Active_Objects/AO2.cpp b/examples/APG/Active_Objects/AO2.cpp
new file mode 100644
index 00000000000..c2bd7ae4e16
--- /dev/null
+++ b/examples/APG/Active_Objects/AO2.cpp
@@ -0,0 +1,197 @@
+// $Id$
+
+#include "ace/Activation_Queue.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;
+ ((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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Future<int>;
+template class ACE_Future_Rep<int>;
+template class ACE_Future_Observer<int>;
+template class ACE_Unbounded_Set<ACE_Future_Observer<int> *>;
+template class ACE_Node<ACE_Future_Observer<int> *>;
+template class ACE_Unbounded_Set_Iterator<ACE_Future_Observer<int> *>;
+template class ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate ACE_Future<int>;
+pragma instantiate ACE_Future_Rep<int>;
+pragma instantiate ACE_Future_Observer<int>;
+pragma instantiate ACE_Unbounded_Set<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Node<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Future_Observer<int> *>;
+pragma instantiate ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Active_Objects/Makefile b/examples/APG/Active_Objects/Makefile
new file mode 100644
index 00000000000..6dd1082ba0c
--- /dev/null
+++ b/examples/APG/Active_Objects/Makefile
@@ -0,0 +1,15 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = AO \
+ AO2
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Active_Objects/active_objects.mpc b/examples/APG/Active_Objects/active_objects.mpc
new file mode 100644
index 00000000000..03bfd27a610
--- /dev/null
+++ b/examples/APG/Active_Objects/active_objects.mpc
@@ -0,0 +1,13 @@
+project(AO) : aceexe {
+ exename = AO
+ Source_Files {
+ AO.cpp
+ }
+}
+
+project(AO2) : aceexe {
+ exename = AO2
+ Source_Files {
+ AO2.cpp
+ }
+}
diff --git a/examples/APG/Active_Objects/active_objects.mwc b/examples/APG/Active_Objects/active_objects.mwc
new file mode 100644
index 00000000000..f27cf43bfc9
--- /dev/null
+++ b/examples/APG/Active_Objects/active_objects.mwc
@@ -0,0 +1,3 @@
+workspace {
+ active_objects.mpc
+}
diff --git a/examples/APG/Config/ARGV_Example.cpp b/examples/APG/Config/ARGV_Example.cpp
new file mode 100644
index 00000000000..a574f95c409
--- /dev/null
+++ b/examples/APG/Config/ARGV_Example.cpp
@@ -0,0 +1,60 @@
+/**
+ * $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/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/examples/APG/Config/Get_Opt.cpp b/examples/APG/Config/Get_Opt.cpp
new file mode 100644
index 00000000000..06902dfa432
--- /dev/null
+++ b/examples/APG/Config/Get_Opt.cpp
@@ -0,0 +1,58 @@
+/**
+ * $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/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/examples/APG/Config/Get_Opt_Long.cpp b/examples/APG/Config/Get_Opt_Long.cpp
new file mode 100644
index 00000000000..f41bd0abba3
--- /dev/null
+++ b/examples/APG/Config/Get_Opt_Long.cpp
@@ -0,0 +1,47 @@
+/**
+ * $Id$
+ *
+ * ACE_Get_Opt long_only examples. Sample code from The ACE
+ * Programmer's Guide, Copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#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/examples/APG/Config/HASTATUS_export.h b/examples/APG/Config/HASTATUS_export.h
new file mode 100644
index 00000000000..6b86e77dc82
--- /dev/null
+++ b/examples/APG/Config/HASTATUS_export.h
@@ -0,0 +1,50 @@
+
+// -*- 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 (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/examples/APG/Config/HA_Status.cpp b/examples/APG/Config/HA_Status.cpp
new file mode 100644
index 00000000000..7cc28f2a3f4
--- /dev/null
+++ b/examples/APG/Config/HA_Status.cpp
@@ -0,0 +1,93 @@
+/**
+ * $Id$
+ *
+ * Home Automation Status server. Sample code from The ACE Programmer's Guide,
+ * Copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#include "ace/Configuration.h"
+#include "ace/Configuration_Import_Export.h"
+#include "ace/Get_Opt.h"
+#include "HA_Status.h"
+
+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_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);
+ }
+ // 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 (ACE_static_cast (u_short, status_port));
+ // Listing 2
+
+ return 0;
+}
+
+int main (int argc, char *argv[])
+{
+ HA_Status status;
+ status.init (argc, argv);
+ return 0;
+}
+
+// These are wrong, just here for an example
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+ template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+ template class ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+# pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+# pragma instantiate ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Config/HA_Status.h b/examples/APG/Config/HA_Status.h
new file mode 100644
index 00000000000..a27937fa133
--- /dev/null
+++ b/examples/APG/Config/HA_Status.h
@@ -0,0 +1,85 @@
+/**
+ * $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_
+
+#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"
+
+// Listing 10
+class ClientHandler :
+ public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+{
+public:
+ typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super;
+
+ ClientHandler()
+ : super()
+ {
+ // Exclude 10
+ ACE_DEBUG(( LM_INFO,
+ "ClientHandler ctor\n"
+ ));
+ // Exclude 10
+ }
+// Listing 10
+
+ ~ClientHandler()
+ {
+ ACE_DEBUG(( LM_INFO,
+ "ClientHandler dtor\n"
+ ));
+ }
+
+// Listing 13
+ int handle_input (ACE_HANDLE)
+ {
+ char buf[64];
+ int bytesReceived;
+
+ if( (bytesReceived =
+ this->peer_.recv( buf, sizeof(buf)-1 )) < 1 )
+ {
+ ACE_DEBUG(( LM_INFO,
+ "ClientHandler handle_input: "
+ "Received %d bytes. Leaving.\n",
+ bytesReceived
+ ));
+ return -1;
+ }
+
+ buf[bytesReceived] = 0;
+ ACE_DEBUG(( LM_INFO,
+ "ClientHandler handle_input: %s\n",
+ buf
+ ));
+
+ return 0;
+ }
+};
+// Listing 13
+
+
+class HASTATUS_Export HA_Status : public ACE_Service_Object
+{
+public:
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+
+private:
+ ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR> acceptor_;
+ ACE_INET_Addr listen_addr_;
+};
+
+#endif /* __HASTATUS_H_ */
diff --git a/examples/APG/Config/Makefile b/examples/APG/Config/Makefile
new file mode 100644
index 00000000000..39299b5f8cb
--- /dev/null
+++ b/examples/APG/Config/Makefile
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Get_Opt Get_Opt_Long ARGV_Example
+LIB = libHA_Status.a
+SHLIB = libHA_Status.$(SOEXT)
+
+LSRC = HA_Status.cpp
+
+LIBS += $(ACELIB)
+
+BUILD = $(VLIB) $(VSHLIB) $(VBIN)
+
+SOURCES = HA_Status.cpp Get_Opt.cpp Get_Opt_Long.cpp ARGV_Example.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Config/config.mpc b/examples/APG/Config/config.mpc
new file mode 100644
index 00000000000..cf2a6f39b7e
--- /dev/null
+++ b/examples/APG/Config/config.mpc
@@ -0,0 +1,28 @@
+project(HA Status) : acelib {
+ sharedname = HA_Status
+ dllflags = HASTATUS_BUILD_DLL
+ 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/examples/APG/Config/config.mwc b/examples/APG/Config/config.mwc
new file mode 100644
index 00000000000..2258cdb6730
--- /dev/null
+++ b/examples/APG/Config/config.mwc
@@ -0,0 +1,3 @@
+workspace {
+ config.mpc
+}
diff --git a/examples/APG/Containers/Allocator.cpp b/examples/APG/Containers/Allocator.cpp
new file mode 100644
index 00000000000..48cb79e60f5
--- /dev/null
+++ b/examples/APG/Containers/Allocator.cpp
@@ -0,0 +1,102 @@
+// $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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Unbounded_Stack<DataElement>
+;
+template class ACE_Node<DataElement>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Unbounded_Stack<DataElement>
+#pragma instantiate ACE_Node<DataElement>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/Array.cpp b/examples/APG/Containers/Array.cpp
new file mode 100644
index 00000000000..1adefdc56f8
--- /dev/null
+++ b/examples/APG/Containers/Array.cpp
@@ -0,0 +1,49 @@
+// $Id$
+
+#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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Array <DataElement*>
+;
+template class ACE_Array_Base<DataElement*>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Array <DataElement*>
+#pragma instantiate ACE_Array_Base<DataElement*>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/DLList.cpp b/examples/APG/Containers/DLList.cpp
new file mode 100644
index 00000000000..521611161d6
--- /dev/null
+++ b/examples/APG/Containers/DLList.cpp
@@ -0,0 +1,128 @@
+// $Id$
+
+#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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_DLList <DataElement>;
+template class ACE_DLList_Iterator <DataElement>;
+template class ACE_DLList_Reverse_Iterator <DataElement>;
+template class ACE_Double_Linked_List<ACE_DLList_Node>;
+template class ACE_Double_Linked_List_Iterator_Base<ACE_DLList_Node>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_DLList <DataElement>
+#pragma instantiate ACE_DLList_Iterator <DataElement*>
+#pragma instantiate ACE_DLList_Reverse_Iterator <DataElement*>
+#pragma instantiate ACE_Double_Linked_List<ACE_DLList_Node>;
+#pragma instantiate ACE_Double_Linked_List_Iterator_Base<ACE_DLList_Node>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/DataElement.h b/examples/APG/Containers/DataElement.h
new file mode 100644
index 00000000000..0a4a1a02fde
--- /dev/null
+++ b/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 () { 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/examples/APG/Containers/Hash_Map.cpp b/examples/APG/Containers/Hash_Map.cpp
new file mode 100644
index 00000000000..a81dbd47061
--- /dev/null
+++ b/examples/APG/Containers/Hash_Map.cpp
@@ -0,0 +1,134 @@
+// $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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class Hash_Map <int, DataElement>
+;
+template class ACE_Hash_Map_Manager_Ex<int, DataElement, ACE_Hash<int>, ACE_Equal_To<int>, ACE_Null_Mutex>
+;
+template class ACE_Hash_Map_Entry<int, DataElement>
+;
+template class ACE_Hash_Map_Iterator_Base_Ex<int, DataElement, ACE_Hash<int>, ACE_Equal_To<int>, ACE_Null_Mutex>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate Hash_Map <int, DataElement*>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<int, DataElement, ACE_Hash<int>, ACE_Equal_To<int>, ACE_Null_Mutex>;
+#pragma instantiate ACE_Hash_Map_Entry<int, DataElement>;
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<int, DataElement, ACE_Hash<int>, ACE_Equal_To<int>, ACE_Null_Mutex>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
+
diff --git a/examples/APG/Containers/Hash_Map_Hash.cpp b/examples/APG/Containers/Hash_Map_Hash.cpp
new file mode 100644
index 00000000000..24f2edd45f7
--- /dev/null
+++ b/examples/APG/Containers/Hash_Map_Hash.cpp
@@ -0,0 +1,129 @@
+// $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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Hash_Map_Manager_Ex<KeyType, DataElement, ACE_Hash<KeyType>, ACE_Equal_To<KeyType>, ACE_Null_Mutex>
+;
+template class Hash_Map <KeyType, DataElement>
+;
+template class ACE_Hash_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Hash_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Hash_Map_Iterator_Base_Ex<KeyType, DataElement, ACE_Hash<KeyType>, ACE_Equal_To<KeyType>, ACE_Null_Mutex>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate Hash_Map <KeyType, DataElement>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<KeyType, DataElement,ACE_Hash<KeyType>, ACE_Equal_To<KeyType>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<KeyType, DataElement, ACE_Hash<KeyType>, ACE_Equal_To<KeyType>, ACE_Null_Mutex>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/Hash_Map_Hash.h b/examples/APG/Containers/Hash_Map_Hash.h
new file mode 100644
index 00000000000..6ac65e0f1be
--- /dev/null
+++ b/examples/APG/Containers/Hash_Map_Hash.h
@@ -0,0 +1,52 @@
+/* -*- 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_;
+};
+
+// Specialize the hash functor.
+ACE_TEMPLATE_SPECIALIZATION
+class ACE_Hash<KeyType>
+{
+public:
+ u_long operator() (const KeyType kt) const
+ {
+ int val = kt;
+ return (u_long)val;
+ }
+};
+
+
+// Specialize the equality functor.
+ACE_TEMPLATE_SPECIALIZATION
+class ACE_Equal_To<KeyType>
+{
+public:
+ int operator() (const KeyType& kt1,
+ const KeyType& kt2) const
+ {
+ int val1 = kt1;
+ int val2 = kt2;
+ return (val1 == val2);
+ }
+};
+// Listing 1
+
+#endif /* __HASH_MAP_HASH_H_ */
diff --git a/examples/APG/Containers/KeyType.h b/examples/APG/Containers/KeyType.h
new file mode 100644
index 00000000000..268b56c1684
--- /dev/null
+++ b/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/examples/APG/Containers/Makefile b/examples/APG/Containers/Makefile
new file mode 100644
index 00000000000..64dd6bc51b0
--- /dev/null
+++ b/examples/APG/Containers/Makefile
@@ -0,0 +1,30 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = DLList \
+ Stacks \
+ Queues \
+ Array \
+ Sets \
+ Map_Manager \
+ Map_Manager_Specialization \
+ Hash_Map \
+ Hash_Map_Hash \
+ RB_Tree \
+ RB_Tree_Functors \
+ Allocator
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/Containers/Map_Manager.cpp b/examples/APG/Containers/Map_Manager.cpp
new file mode 100644
index 00000000000..4dce09fd2a0
--- /dev/null
+++ b/examples/APG/Containers/Map_Manager.cpp
@@ -0,0 +1,135 @@
+// $Id$
+
+#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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Entry<KeyType,DataElement>
+;
+template class ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Entry<KeyType,DataElement>
+#pragma instantiate ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
diff --git a/examples/APG/Containers/Map_Manager_Specialization.cpp b/examples/APG/Containers/Map_Manager_Specialization.cpp
new file mode 100644
index 00000000000..225f07e98c8
--- /dev/null
+++ b/examples/APG/Containers/Map_Manager_Specialization.cpp
@@ -0,0 +1,170 @@
+// $Id$
+
+#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_;
+};
+
+ACE_TEMPLATE_SPECIALIZATION
+int
+ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::equal
+(const KeyType& r1, const KeyType &r2)
+{
+ return (r1 == r2);
+}
+// Listing 1
+#else
+ACE_TEMPLATE_SPECIALIZATION
+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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Entry<KeyType,DataElement>
+;
+template class ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+template class ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
+#pragma instantiate ACE_Map_Entry<KeyType,DataElement>
+#pragma instantiate ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Containers/Queues.cpp b/examples/APG/Containers/Queues.cpp
new file mode 100644
index 00000000000..45d3e7786bb
--- /dev/null
+++ b/examples/APG/Containers/Queues.cpp
@@ -0,0 +1,129 @@
+// $Id$
+
+#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;
+ int i;
+ for (i = 0; i < 10; i++)
+ {
+ DataElement elem[10];
+ elem[i].setData (9-i);
+ queue.enqueue_head (elem[i]);
+ }
+
+ for (i = 0; i< 10; i++)
+ {
+ DataElement elem[10];
+ elem[i].setData (i+10);
+ queue.enqueue_tail (elem[i]);
+ }
+
+ for (ACE_Unbounded_Queue_Iterator<DataElement> iter (queue);
+ !iter.done ();
+ iter.advance ())
+ {
+ DataElement *elem;
+ 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;
+ 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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Unbounded_Queue<DataElement*>
+;
+template class ACE_Unbounded_Queue_Iterator<DataElement*>
+;
+template class ACE_Unbounded_Queue<DataElement>
+;
+template class ACE_Unbounded_Queue_Iterator<DataElement>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Unbounded_Queue<DataElement*>
+#pragma instantiate ACE_Unbounded_Queue_Iterator<DataElement*>
+#pragma instantiate ACE_Unbounded_Queue<DataElement>
+#pragma instantiate ACE_Unbounded_Queue_Iterator<DataElement>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/RB_Tree.cpp b/examples/APG/Containers/RB_Tree.cpp
new file mode 100644
index 00000000000..09e4bf36308
--- /dev/null
+++ b/examples/APG/Containers/RB_Tree.cpp
@@ -0,0 +1,158 @@
+// $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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_RB_Tree <int, DataElement*,
+ACE_Less_Than<int>, ACE_Null_Mutex>
+;
+template class Tree <int, DataElement*>
+;
+template class ACE_RB_Tree_Iterator_Base<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Iterator<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Reverse_Iterator<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Node<int, DataElement*>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_RB_Tree <int, DataElement*,ACE_Less_Than<int>, ACE_Null_Mutex>
+#pragma instantiate ACE_Less_Than <int>
+#pragma instantiate Tree <int, DataElement*>
+#pragma instantiate ACE_RB_Tree_Iterator_Base<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Iterator<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Reverse_Iterator<int, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Node<int, DataElement*>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/RB_Tree_Functors.cpp b/examples/APG/Containers/RB_Tree_Functors.cpp
new file mode 100644
index 00000000000..06753d5fc68
--- /dev/null
+++ b/examples/APG/Containers/RB_Tree_Functors.cpp
@@ -0,0 +1,156 @@
+// $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;
+ 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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_RB_Tree <KeyType, DataElement*,
+ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+;
+template class Tree <KeyType, DataElement*>
+;
+template class ACE_RB_Tree_Iterator_Base<KeyType, DataElement*, ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Iterator<KeyType, DataElement*, ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Reverse_Iterator<KeyType, DataElement*, ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+;
+template class ACE_RB_Tree_Node<KeyType, DataElement*>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_RB_Tree <KeyType, DataElement*,ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+#pragma instantiate Tree <KeyType, DataElement*>
+#pragma instantiate ACE_RB_Tree_Iterator_Base<KeyType, DataElement*, ACE_Less_Than<int>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Iterator<KeyType, DataElement*, ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Reverse_Iterator<KeyType, DataElement*, ACE_Less_Than<KeyType>, ACE_Null_Mutex>
+#pragma instantiate ACE_RB_Tree_Node<KeyType, DataElement*>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/RB_Tree_Functors.h b/examples/APG/Containers/RB_Tree_Functors.h
new file mode 100644
index 00000000000..3eafa89bb30
--- /dev/null
+++ b/examples/APG/Containers/RB_Tree_Functors.h
@@ -0,0 +1,32 @@
+/* -*- 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_TEMPLATE_SPECIALIZATION
+class ACE_Less_Than<KeyType>
+{
+public:
+ int operator() (const KeyType k1, const KeyType k2)
+ { return k1 < k2; }
+};
+// Listing 1
+
+#endif /* __RB_TREE_FUNCTORS_H_ */
diff --git a/examples/APG/Containers/Sets.cpp b/examples/APG/Containers/Sets.cpp
new file mode 100644
index 00000000000..06286a90e30
--- /dev/null
+++ b/examples/APG/Containers/Sets.cpp
@@ -0,0 +1,134 @@
+// $Id$
+
+#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;
+}
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Unbounded_Set<DataElement*>
+;
+template class ACE_Unbounded_Set_Iterator<DataElement*>
+;
+template class ACE_Bounded_Set<DataElement>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Unbounded_Set<DataElement*>
+#pragma instantitate ACE_Unbounded_Set_Iterator<DataElement*>
+#pragma instantiate ACE_Bounded_Set<DataElement>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/Stacks.cpp b/examples/APG/Containers/Stacks.cpp
new file mode 100644
index 00000000000..5f94066979a
--- /dev/null
+++ b/examples/APG/Containers/Stacks.cpp
@@ -0,0 +1,161 @@
+// $Id$
+
+#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;
+ 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;
+ 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 ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Bounded_Stack<DataElement*>;
+template class ACE_Bounded_Stack<DataElement>;
+template class ACE_Fixed_Stack<DataElement*, 100>;
+template class ACE_Unbounded_Stack<DataElement>;
+template class ACE_Unbounded_Stack<DataElement*>;
+template class ACE_Unbounded_Stack_Iterator<DataElement>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragam instantiate ACE_Bounded_Stack<DataElement>
+#pragma instantiate ACE_Bounded_Stack<DataElement*>
+#pragma instantiate ACE_Fixed_Stack<DataElement*, 100>
+#pragma instantiate ACE_Unbounded_Stack<DataElement>
+#pragma instantiate ACE_Unbounded_Stack<DataElement*>
+#pragma instantiate ACE_Unbounded_Stack_Iterator<DataElement>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/
diff --git a/examples/APG/Containers/containers.mpc b/examples/APG/Containers/containers.mpc
new file mode 100644
index 00000000000..a8c503540a4
--- /dev/null
+++ b/examples/APG/Containers/containers.mpc
@@ -0,0 +1,83 @@
+project(DLList) : aceexe {
+ 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/examples/APG/Containers/containers.mwc b/examples/APG/Containers/containers.mwc
new file mode 100644
index 00000000000..0f4dd2dbb8b
--- /dev/null
+++ b/examples/APG/Containers/containers.mwc
@@ -0,0 +1,3 @@
+workspace {
+ containers.mpc
+}
diff --git a/examples/APG/Logging/Callback-2.h b/examples/APG/Logging/Callback-2.h
new file mode 100644
index 00000000000..5d796cf1473
--- /dev/null
+++ b/examples/APG/Logging/Callback-2.h
@@ -0,0 +1,38 @@
+// $Id$
+
+#include "ace/streams.h"
+#include "ace/Log_Msg_Callback.h"
+#include "ace/Log_Record.h"
+#include "ace/SString.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 =
+ ACE_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;
+ }
+};
+
diff --git a/examples/APG/Logging/Callback-3.h b/examples/APG/Logging/Callback-3.h
new file mode 100644
index 00000000000..da852cb847c
--- /dev/null
+++ b/examples/APG/Logging/Callback-3.h
@@ -0,0 +1,59 @@
+// $Id$
+
+#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_)
+ {
+ log_record.print
+ (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, cerr);
+ 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_;
+};
diff --git a/examples/APG/Logging/Callback.h b/examples/APG/Logging/Callback.h
new file mode 100644
index 00000000000..264c99bd9c1
--- /dev/null
+++ b/examples/APG/Logging/Callback.h
@@ -0,0 +1,15 @@
+// $Id$
+
+#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) {
+ log_record.print (ACE_TEXT (""), 0, cerr);
+ log_record.print (ACE_TEXT (""), ACE_Log_Msg::VERBOSE, cerr);
+ }
+};
diff --git a/examples/APG/Logging/Change_Instance_Default.cpp b/examples/APG/Logging/Change_Instance_Default.cpp
new file mode 100644
index 00000000000..e22af840259
--- /dev/null
+++ b/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/examples/APG/Logging/Change_Mask.cpp b/examples/APG/Logging/Change_Mask.cpp
new file mode 100644
index 00000000000..4cd0deac7e5
--- /dev/null
+++ b/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 (ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_NOTICE, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/Howto_Syslog.cpp b/examples/APG/Logging/Howto_Syslog.cpp
new file mode 100644
index 00000000000..0bafab546b7
--- /dev/null
+++ b/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 (ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/LogManager.h b/examples/APG/Logging/LogManager.h
new file mode 100644
index 00000000000..33d82b26e8a
--- /dev/null
+++ b/examples/APG/Logging/LogManager.h
@@ -0,0 +1,101 @@
+// $Id$
+
+#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:
+ std::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 std::ofstream ();
+ log_stream_->open (filename, ios::out | ios::app);
+ this->redirectToOStream (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/examples/APG/Logging/Log_Msg_Alt.h b/examples/APG/Logging/Log_Msg_Alt.h
new file mode 100644
index 00000000000..c78d2bd1f4a
--- /dev/null
+++ b/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/examples/APG/Logging/Makefile b/examples/APG/Logging/Makefile
new file mode 100644
index 00000000000..6f1b9eb9065
--- /dev/null
+++ b/examples/APG/Logging/Makefile
@@ -0,0 +1,36 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Simple1 \
+ Simple2 \
+ Change_Mask \
+ Change_Instance_Default \
+ Wrap_Macros \
+ Wrap_Macros_Alt \
+ Trace_Return \
+ Use_Stderr \
+ Howto_Syslog \
+ Use_Syslog \
+ Use_Ostream \
+ Use_Multiple_Sinks \
+ Use_Callback \
+ Use_Callback2 \
+ Use_Logger \
+ Use_Logging_Server \
+ Use_LogManager \
+ Use_Logging_Strategy
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+HEADERS = $(wildcard *.h)
+
+TEXTS = server.conf client.conf logging_strategy.conf
+
+CFLAGS += -DACE_NTRACE=0
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Logging/Simple1.cpp b/examples/APG/Logging/Simple1.cpp
new file mode 100644
index 00000000000..93c8b681c23
--- /dev/null
+++ b/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(ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/Simple2.cpp b/examples/APG/Logging/Simple2.cpp
new file mode 100644
index 00000000000..dfec1c68dd2
--- /dev/null
+++ b/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 (ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_NOTICE, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/Trace.h b/examples/APG/Logging/Trace.h
new file mode 100644
index 00000000000..8662eb3c8e6
--- /dev/null
+++ b/examples/APG/Logging/Trace.h
@@ -0,0 +1,151 @@
+// $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)
+# 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__)
+// This stuff only works with g++...
+
+// 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/examples/APG/Logging/Trace_Return.cpp b/examples/APG/Logging/Trace_Return.cpp
new file mode 100644
index 00000000000..71b04f0e0b7
--- /dev/null
+++ b/examples/APG/Logging/Trace_Return.cpp
@@ -0,0 +1,39 @@
+// $Id$
+
+#if defined (__GNUC__)
+// The DEBUG stuff only works with g++...
+
+// Listing 1 code/ch03
+#include "Trace.h"
+
+void foo (void);
+
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ TRACE (ACE_TEXT ("main"));
+
+ MY_DEBUG (ACE_TEXT ("Hi Mom\n"));
+ foo ();
+ MY_DEBUG (ACE_TEXT ("Goodnight\n"));
+
+ TRACE_RETURN (0);
+}
+
+void foo (void)
+{
+ TRACE (ACE_TEXT ("foo"));
+ MY_DEBUG (ACE_TEXT ("Howdy Pardner\n"));
+ TRACE_RETURN_VOID ();
+}
+// Listing 1
+
+#else
+#include <stdio.h>
+
+int main (int, char *[])
+{
+ puts ("This example only works on g++\n");
+ return 0;
+}
+
+#endif /* __GNUC__ */
diff --git a/examples/APG/Logging/Use_Callback.cpp b/examples/APG/Logging/Use_Callback.cpp
new file mode 100644
index 00000000000..2deff99f4ea
--- /dev/null
+++ b/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 (ACE_TEXT ("main"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n")));
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));
+
+ return 0;
+}
diff --git a/examples/APG/Logging/Use_Callback2.cpp b/examples/APG/Logging/Use_Callback2.cpp
new file mode 100644
index 00000000000..a3f005e5949
--- /dev/null
+++ b/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 (ACE_TEXT ("main"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n")));
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));
+
+ return 0;
+}
diff --git a/examples/APG/Logging/Use_LogManager.cpp b/examples/APG/Logging/Use_LogManager.cpp
new file mode 100644
index 00000000000..328f00416ee
--- /dev/null
+++ b/examples/APG/Logging/Use_LogManager.cpp
@@ -0,0 +1,37 @@
+// $Id$
+
+#include "LogManager.h"
+
+// Listing 1 code/ch03
+void foo (void);
+
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ LOG_MANAGER->redirectToStderr ();
+ ACE_TRACE (ACE_TEXT ("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 (ACE_TEXT ("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_TEMPLATE_INSTANTIATION)
+ template class ACE_Singleton<LogManager, ACE_Null_Mutex>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Singleton<LogManager, ACE_Null_Mutex>
+#elif defined (__GNUC__) && (defined (_AIX) || defined (__hpux))
+template ACE_Singleton<LogManager, ACE_Null_Mutex> *
+ ACE_Singleton<LogManager, ACE_Null_Mutex>::singleton_;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+// Listing 2
diff --git a/examples/APG/Logging/Use_Logger.cpp b/examples/APG/Logging/Use_Logger.cpp
new file mode 100644
index 00000000000..9dd00caee42
--- /dev/null
+++ b/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 (ACE_TEXT ("main"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n")));
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));
+
+ return 0;
+}
diff --git a/examples/APG/Logging/Use_Logging_Server.cpp b/examples/APG/Logging/Use_Logging_Server.cpp
new file mode 100644
index 00000000000..1d304f2577b
--- /dev/null
+++ b/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 (ACE_TEXT ("main"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%IHi Mom\n")));
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));
+
+ return 0;
+}
diff --git a/examples/APG/Logging/Use_Logging_Strategy.cpp b/examples/APG/Logging/Use_Logging_Strategy.cpp
new file mode 100644
index 00000000000..0bf1e67afd5
--- /dev/null
+++ b/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 (ACE_TEXT ("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/examples/APG/Logging/Use_Multiple_Sinks.cpp b/examples/APG/Logging/Use_Multiple_Sinks.cpp
new file mode 100644
index 00000000000..5a8aa55e81a
--- /dev/null
+++ b/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 (ACE_TEXT ("main"));
+
+ ACE_OSTREAM_TYPE *output =
+ new std::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/examples/APG/Logging/Use_Ostream.cpp b/examples/APG/Logging/Use_Ostream.cpp
new file mode 100644
index 00000000000..87a84f9f6d9
--- /dev/null
+++ b/examples/APG/Logging/Use_Ostream.cpp
@@ -0,0 +1,37 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/streams.h"
+
+void foo (void);
+
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_TRACE (ACE_TEXT ("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 =
+ new std::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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/Use_Stderr.cpp b/examples/APG/Logging/Use_Stderr.cpp
new file mode 100644
index 00000000000..3b087a09af4
--- /dev/null
+++ b/examples/APG/Logging/Use_Stderr.cpp
@@ -0,0 +1,39 @@
+// $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 (ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
+
+}
diff --git a/examples/APG/Logging/Use_Syslog.cpp b/examples/APG/Logging/Use_Syslog.cpp
new file mode 100644
index 00000000000..ef0cc8857f2
--- /dev/null
+++ b/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 (ACE_TEXT ("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 (ACE_TEXT ("foo"));
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
+}
diff --git a/examples/APG/Logging/Wrap_Macros.cpp b/examples/APG/Logging/Wrap_Macros.cpp
new file mode 100644
index 00000000000..1a272a8abe8
--- /dev/null
+++ b/examples/APG/Logging/Wrap_Macros.cpp
@@ -0,0 +1,36 @@
+// $Id$
+
+#if defined (__GNUC__)
+// The macros in Trace.h only work on g++
+
+// Listing 1 code/ch03
+#include "Trace.h"
+
+void foo (void);
+
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_TRACE (ACE_TEXT ("main"));
+ MY_DEBUG (ACE_TEXT ("Hi Mom\n"));
+ foo ();
+ MY_DEBUG (ACE_TEXT ("Goodnight\n"));
+ return 0;
+}
+
+void foo (void)
+{
+ ACE_TRACE (ACE_TEXT ("foo"));
+ MY_DEBUG (ACE_TEXT ("Howdy Pardner\n"));
+}
+// Listing 1
+
+#else
+#include <stdio.h>
+
+int main (int, char *[])
+{
+ puts ("This example only works on g++\n");
+ return 0;
+}
+
+#endif /* __GNUC__ */
diff --git a/examples/APG/Logging/Wrap_Macros_Alt.cpp b/examples/APG/Logging/Wrap_Macros_Alt.cpp
new file mode 100644
index 00000000000..1926f001d36
--- /dev/null
+++ b/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 (ACE_TEXT ("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/examples/APG/Logging/client.conf b/examples/APG/Logging/client.conf
new file mode 100644
index 00000000000..1007e3aa7f6
--- /dev/null
+++ b/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/examples/APG/Logging/logging.mpc b/examples/APG/Logging/logging.mpc
new file mode 100644
index 00000000000..de7690d6290
--- /dev/null
+++ b/examples/APG/Logging/logging.mpc
@@ -0,0 +1,125 @@
+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/examples/APG/Logging/logging.mwc b/examples/APG/Logging/logging.mwc
new file mode 100644
index 00000000000..d3d6dd0fc12
--- /dev/null
+++ b/examples/APG/Logging/logging.mwc
@@ -0,0 +1,3 @@
+workspace {
+ logging.mpc
+}
diff --git a/examples/APG/Logging/logging_strategy.conf b/examples/APG/Logging/logging_strategy.conf
new file mode 100644
index 00000000000..b63501ee185
--- /dev/null
+++ b/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/examples/APG/Logging/server.conf b/examples/APG/Logging/server.conf
new file mode 100644
index 00000000000..31f8fd95d9d
--- /dev/null
+++ b/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/examples/APG/Makefile b/examples/APG/Makefile
new file mode 100644
index 00000000000..387eebcb424
--- /dev/null
+++ b/examples/APG/Makefile
@@ -0,0 +1,40 @@
+#----------------------------------------------------------------------------
+# $Id$
+#
+# Makefile for the ACE examples/APG directory
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# Local macros
+#----------------------------------------------------------------------------
+
+DIRS = Active_Objects \
+ Config \
+ Containers \
+ Logging \
+ Misc_IPC \
+ Naming \
+ Proactor \
+ Processes \
+ Reactor \
+ Shared_Memory \
+ Signals \
+ Sockets \
+ Streams \
+ Svc_Config \
+ Threads \
+ ThreadManagement \
+ ThreadPools \
+ ThreadSafety \
+ Timers
+
+#----------------------------------------------------------------------------
+# Include macros and targets
+#----------------------------------------------------------------------------
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nolocal.GNU
diff --git a/examples/APG/Misc_IPC/Makefile b/examples/APG/Misc_IPC/Makefile
new file mode 100644
index 00000000000..e62e2bc6ee6
--- /dev/null
+++ b/examples/APG/Misc_IPC/Makefile
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = UDP_Unicast UDP_Broadcast UDP_Multicast
+
+SOURCES = UDP_Unicast.cpp UDP_Broadcast.cpp UDP_Multicast.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Misc_IPC/UDP_Broadcast.cpp b/examples/APG/Misc_IPC/UDP_Broadcast.cpp
new file mode 100644
index 00000000000..8f3fe58c1b5
--- /dev/null
+++ b/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.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 (ACE_static_cast (u_short, 10101));
+ ACE_SOCK_Dgram_Bcast udp (my_addr);
+ ssize_t sent = udp.send (message,
+ ACE_OS_String::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/examples/APG/Misc_IPC/UDP_Multicast.cpp b/examples/APG/Misc_IPC/UDP_Multicast.cpp
new file mode 100644
index 00000000000..a21b02efc69
--- /dev/null
+++ b/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.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_String::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/examples/APG/Misc_IPC/UDP_Unicast.cpp b/examples/APG/Misc_IPC/UDP_Unicast.cpp
new file mode 100644
index 00000000000..6a6c6f6a2e4
--- /dev/null
+++ b/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.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 (ACE_static_cast (u_short, 10101));
+ ACE_SOCK_Dgram udp (my_addr);
+ ssize_t sent = udp.send (message,
+ ACE_OS_String::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 (ACE_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, ACE_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/examples/APG/Misc_IPC/misc_ipc.mpc b/examples/APG/Misc_IPC/misc_ipc.mpc
new file mode 100644
index 00000000000..d59a5e01e16
--- /dev/null
+++ b/examples/APG/Misc_IPC/misc_ipc.mpc
@@ -0,0 +1,20 @@
+project(UDP Broadcast) : aceexe {
+ exename = UDP_Broadcast
+ Source_Files {
+ UDP_Broadcast.cpp
+ }
+}
+
+project(UDP Multicast) : aceexe {
+ exename = UDP_Multicast
+ Source_Files {
+ UDP_Multicast.cpp
+ }
+}
+
+project(UDP Unicast) : aceexe {
+ exename = UDP_Unicast
+ Source_Files {
+ UDP_Unicast.cpp
+ }
+}
diff --git a/examples/APG/Misc_IPC/misc_ipc.mwc b/examples/APG/Misc_IPC/misc_ipc.mwc
new file mode 100644
index 00000000000..7ac6239a69f
--- /dev/null
+++ b/examples/APG/Misc_IPC/misc_ipc.mwc
@@ -0,0 +1,3 @@
+workspace {
+ misc_ipc.mpc
+}
diff --git a/examples/APG/Naming/EMail.h b/examples/APG/Naming/EMail.h
new file mode 100644
index 00000000000..fc38913a10a
--- /dev/null
+++ b/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/examples/APG/Naming/Graph.cpp b/examples/APG/Naming/Graph.cpp
new file mode 100644
index 00000000000..cff8e37244e
--- /dev/null
+++ b/examples/APG/Naming/Graph.cpp
@@ -0,0 +1,48 @@
+// $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 %s\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/examples/APG/Naming/Graph.h b/examples/APG/Naming/Graph.h
new file mode 100644
index 00000000000..135b7d14f77
--- /dev/null
+++ b/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/examples/APG/Naming/Graphable_Element.cpp b/examples/APG/Naming/Graphable_Element.cpp
new file mode 100644
index 00000000000..6b5d6c755e6
--- /dev/null
+++ b/examples/APG/Naming/Graphable_Element.cpp
@@ -0,0 +1,13 @@
+// $Id$
+
+#include "Graphable_Element.h"
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class _List_base<Graphable_Element, allocator<Graphable_Element> >;
+template void list<Graphable_Element, allocator<Graphable_Element> >::sort(void);
+template void list<Graphable_Element, allocator<Graphable_Element> >::merge(list<Graphable_Element, allocator<Graphable_Element> > &);
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate _List_base<Graphable_Element, allocator<Graphable_Element> >;
+pragma instantiate list<Graphable_Element, allocator<Graphable_Element> >::sort(void);
+pragma instantiate list<Graphable_Element, allocator<Graphable_Element> >::merge(list<Graphable_Element, allocator<Graphable_Element> > &);
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Naming/Graphable_Element.h b/examples/APG/Naming/Graphable_Element.h
new file mode 100644
index 00000000000..cecc691f6f8
--- /dev/null
+++ b/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)
+ {
+ return this->when_;
+ }
+
+ inline float temp (void)
+ {
+ return this->temp_;
+ }
+ // Listing 2
+
+ // Listing 3 code/ch21
+ inline bool operator< (Graphable_Element &other)
+ {
+ 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/examples/APG/Naming/Makefile b/examples/APG/Naming/Makefile
new file mode 100644
index 00000000000..d3316532b97
--- /dev/null
+++ b/examples/APG/Naming/Makefile
@@ -0,0 +1,39 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+MAKEFILE=Makefile
+
+MKLIST = Makefile.netlocal \
+ Makefile.netlocal_reader \
+ Makefile.nodelocal \
+ Makefile.nodelocal_shared \
+ Makefile.nodelocal_shared_reader
+
+## Ensure that Makefiles in MKLIST are executed in sequence during a
+## parallel build because we share some files between multiple libraries.
+## Also, the AIX tempinc directory will get confused.
+.NOTPARALLEL:
+
+## Makefile.*.mkfile is a dummy target which will cause
+## $(MAKE) -f Makefile.* to be invoked, then it cleans
+## up tempinc when needed for AIX Visual Age C++.
+%.mkfile: %
+ @echo $(MAKE) -f $< $(MKFILE_TARGET)
+ @$(MAKE) -f $< $(MKFILE_TARGET)
+ -@$(RM) -rf tempinc
+
+# This rule invokes make again with the list of .mkfile targets as a
+# parameter. For example, if the all target is being made, make is invoked
+# as follows:
+#
+# make -f Makefile MKFILE_TARGET=all Makefile.singles
+
+all clean depend realclean:
+ifneq ($(MKLIST),)
+ @echo $(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+ @$(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+endif
+
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/examples/APG/Naming/Makefile.netlocal b/examples/APG/Naming/Makefile.netlocal
new file mode 100644
index 00000000000..f296f08301d
--- /dev/null
+++ b/examples/APG/Naming/Makefile.netlocal
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Netlocal
+
+SRC = Netlocal.cpp Temperature_Monitor2.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Naming/Makefile.netlocal_reader b/examples/APG/Naming/Makefile.netlocal_reader
new file mode 100644
index 00000000000..1baecddb132
--- /dev/null
+++ b/examples/APG/Naming/Makefile.netlocal_reader
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Netlocal_reader
+
+SRC = Netlocal_reader.cpp Graph.cpp Temperature_Grapher.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Naming/Makefile.nodelocal b/examples/APG/Naming/Makefile.nodelocal
new file mode 100644
index 00000000000..1bf769dab9c
--- /dev/null
+++ b/examples/APG/Naming/Makefile.nodelocal
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Nodelocal
+
+SRC = Nodelocal.cpp Temperature_Monitor.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Naming/Makefile.nodelocal_shared b/examples/APG/Naming/Makefile.nodelocal_shared
new file mode 100644
index 00000000000..719f7344755
--- /dev/null
+++ b/examples/APG/Naming/Makefile.nodelocal_shared
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Nodelocal_shared
+
+SRC = Nodelocal_shared.cpp Temperature_Monitor2.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Naming/Makefile.nodelocal_shared_reader b/examples/APG/Naming/Makefile.nodelocal_shared_reader
new file mode 100644
index 00000000000..2629d6ddd9f
--- /dev/null
+++ b/examples/APG/Naming/Makefile.nodelocal_shared_reader
@@ -0,0 +1,17 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Nodelocal_shared_reader
+
+SRC = Nodelocal_shared_reader.cpp \
+ Graph.cpp \
+ Temperature_Grapher.cpp \
+ Temperature_Monitor.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Naming/Name_Binding.h b/examples/APG/Naming/Name_Binding.h
new file mode 100644
index 00000000000..e170803dffa
--- /dev/null
+++ b/examples/APG/Naming/Name_Binding.h
@@ -0,0 +1,58 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef NAME_BINDING_H
+#define NAME_BINDING_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_;
+ delete this->type_;
+ }
+
+ 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_;
+ const char *type_;
+};
+
+typedef auto_ptr<Name_Binding> Name_Binding_Ptr;
+// Listing 1
+
+#endif /* NAME_BINDING_H */
diff --git a/examples/APG/Naming/Naming_Context.h b/examples/APG/Naming/Naming_Context.h
new file mode 100644
index 00000000000..7c2b245cba4
--- /dev/null
+++ b/examples/APG/Naming/Naming_Context.h
@@ -0,0 +1,67 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef NAMING_CONTEXT_H
+#define NAMING_CONTEXT_H
+
+#include "ace/Naming_Context.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/examples/APG/Naming/Netlocal.cpp b/examples/APG/Naming/Netlocal.cpp
new file mode 100644
index 00000000000..f1799ab3882
--- /dev/null
+++ b/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/examples/APG/Naming/Netlocal_reader.cpp b/examples/APG/Naming/Netlocal_reader.cpp
new file mode 100644
index 00000000000..f77724aabbe
--- /dev/null
+++ b/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/examples/APG/Naming/Nodelocal.cpp b/examples/APG/Naming/Nodelocal.cpp
new file mode 100644
index 00000000000..c8a2d862634
--- /dev/null
+++ b/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
+ char *naming_options_argv[] = { argv[0] };
+ name_options->parse_args
+ (sizeof(naming_options_argv) / sizeof(char*),
+ 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/examples/APG/Naming/Nodelocal_shared.cpp b/examples/APG/Naming/Nodelocal_shared.cpp
new file mode 100644
index 00000000000..34ea87aab2d
--- /dev/null
+++ b/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/examples/APG/Naming/Nodelocal_shared_reader.cpp b/examples/APG/Naming/Nodelocal_shared_reader.cpp
new file mode 100644
index 00000000000..7385f09a496
--- /dev/null
+++ b/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/examples/APG/Naming/Temperature_Grapher.cpp b/examples/APG/Naming/Temperature_Grapher.cpp
new file mode 100644
index 00000000000..6d47e1f8bf6
--- /dev/null
+++ b/examples/APG/Naming/Temperature_Grapher.cpp
@@ -0,0 +1,80 @@
+// $Id$
+
+#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/examples/APG/Naming/Temperature_Grapher.h b/examples/APG/Naming/Temperature_Grapher.h
new file mode 100644
index 00000000000..610dac6a578
--- /dev/null
+++ b/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/examples/APG/Naming/Temperature_Grapher_Options.h b/examples/APG/Naming/Temperature_Grapher_Options.h
new file mode 100644
index 00000000000..9e36a0551fd
--- /dev/null
+++ b/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, char ** 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/examples/APG/Naming/Temperature_Monitor.cpp b/examples/APG/Naming/Temperature_Monitor.cpp
new file mode 100644
index 00000000000..561f045a553
--- /dev/null
+++ b/examples/APG/Naming/Temperature_Monitor.cpp
@@ -0,0 +1,131 @@
+// $Id$
+
+#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/examples/APG/Naming/Temperature_Monitor.h b/examples/APG/Naming/Temperature_Monitor.h
new file mode 100644
index 00000000000..3b85b100fa1
--- /dev/null
+++ b/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/examples/APG/Naming/Temperature_Monitor2.cpp b/examples/APG/Naming/Temperature_Monitor2.cpp
new file mode 100644
index 00000000000..bb84b8c4fc3
--- /dev/null
+++ b/examples/APG/Naming/Temperature_Monitor2.cpp
@@ -0,0 +1,142 @@
+// $Id$
+
+#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()
+{
+ 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;
+
+ 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()
+{
+ 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/examples/APG/Naming/Temperature_Monitor2.h b/examples/APG/Naming/Temperature_Monitor2.h
new file mode 100644
index 00000000000..f09623f15a7
--- /dev/null
+++ b/examples/APG/Naming/Temperature_Monitor2.h
@@ -0,0 +1,35 @@
+// $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();
+
+ protected:
+ void record_temperature(float temp);
+ void record_history(float temp);
+ void record_failure();
+ 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/examples/APG/Naming/Temperature_Monitor_Options.h b/examples/APG/Naming/Temperature_Monitor_Options.h
new file mode 100644
index 00000000000..2dc6469788f
--- /dev/null
+++ b/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, char *[])
+ { }
+
+ 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/examples/APG/Naming/Thermometer.h b/examples/APG/Naming/Thermometer.h
new file mode 100644
index 00000000000..609167874e7
--- /dev/null
+++ b/examples/APG/Naming/Thermometer.h
@@ -0,0 +1,47 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef THERMOMETER_H
+#define THERMOMETER_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/examples/APG/Naming/naming.mpc b/examples/APG/Naming/naming.mpc
new file mode 100644
index 00000000000..1a86f720979
--- /dev/null
+++ b/examples/APG/Naming/naming.mpc
@@ -0,0 +1,42 @@
+project(Netlocal) : aceexe {
+ exename = Netlocal
+ Source_Files {
+ Netlocal.cpp
+ Temperature_Monitor2.cpp
+ }
+}
+
+project(Netlocal Reader) : aceexe {
+ exename = Netlocal_reader
+ Source_Files {
+ Netlocal_reader.cpp
+ Graph.cpp
+ Temperature_Grapher.cpp
+ }
+}
+
+project(Nodelocal) : aceexe {
+ exename = Netlocal
+ Source_Files {
+ Nodelocal.cpp
+ Temperature_Monitor.cpp
+ }
+}
+
+project(Nodelocal Shared) : aceexe {
+ exename = Nodelocal_shared
+ Source_Files {
+ Nodelocal_shared.cpp
+ Temperature_Monitor2.cpp
+ }
+}
+
+project(Nodelocal Shared Reader) : aceexe {
+ exename = Nodelocal_shared_reader
+ Source_Files {
+ Nodelocal_shared_reader.cpp
+ Graph.cpp
+ Temperature_Grapher.cpp
+ Temperature_Monitor.cpp
+ }
+}
diff --git a/examples/APG/Naming/naming.mwc b/examples/APG/Naming/naming.mwc
new file mode 100644
index 00000000000..cdef75bfed2
--- /dev/null
+++ b/examples/APG/Naming/naming.mwc
@@ -0,0 +1,3 @@
+workspace {
+ naming.mpc
+}
diff --git a/examples/APG/Naming/svc.conf b/examples/APG/Naming/svc.conf
new file mode 100644
index 00000000000..550ef992177
--- /dev/null
+++ b/examples/APG/Naming/svc.conf
@@ -0,0 +1 @@
+dynamic Name_Server Service_Object * netsvcs:_make_ACE_Name_Acceptor() "-p 20012"
diff --git a/examples/APG/Proactor/HA_Proactive_Status.cpp b/examples/APG/Proactor/HA_Proactive_Status.cpp
new file mode 100644
index 00000000000..4b84920f523
--- /dev/null
+++ b/examples/APG/Proactor/HA_Proactive_Status.cpp
@@ -0,0 +1,147 @@
+/*
+** $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/Proactor.h"
+
+// 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& remote,
+ const ACE_INET_Addr& local)
+{
+ 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 =
+ ACE_reinterpret_cast (struct in_addr*,
+ remote.get_addr ());
+ struct in_addr *local_addr =
+ ACE_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;
+}
diff --git a/examples/APG/Proactor/HA_Proactive_Status.h b/examples/APG/Proactor/HA_Proactive_Status.h
new file mode 100644
index 00000000000..cef3fe89a7e
--- /dev/null
+++ b/examples/APG/Proactor/HA_Proactive_Status.h
@@ -0,0 +1,81 @@
+/* -*- 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/Service_Object.h"
+// Listing 1 code/ch08
+#include "ace/Asynch_IO.h"
+
+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
+
+#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/examples/APG/Proactor/Makefile b/examples/APG/Proactor/Makefile
new file mode 100644
index 00000000000..e812d025fc7
--- /dev/null
+++ b/examples/APG/Proactor/Makefile
@@ -0,0 +1,12 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = HA_Proactive_Status
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Proactor/proactor.mpc b/examples/APG/Proactor/proactor.mpc
new file mode 100644
index 00000000000..7e592972791
--- /dev/null
+++ b/examples/APG/Proactor/proactor.mpc
@@ -0,0 +1,6 @@
+project(HA Proactive Status) : aceexe {
+ exename = HA_Proactive_Status
+ Source_Files {
+ HA_Proactive_Status.cpp
+ }
+}
diff --git a/examples/APG/Proactor/proactor.mwc b/examples/APG/Proactor/proactor.mwc
new file mode 100644
index 00000000000..60285887963
--- /dev/null
+++ b/examples/APG/Proactor/proactor.mwc
@@ -0,0 +1,3 @@
+workspace {
+ proactor.mpc
+}
diff --git a/examples/APG/Processes/Makefile b/examples/APG/Processes/Makefile
new file mode 100644
index 00000000000..030ef9a064c
--- /dev/null
+++ b/examples/APG/Processes/Makefile
@@ -0,0 +1,17 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Process_Manager_Death \
+ Process_Manager_Spawn \
+ Process_Mutex \
+ Spawn
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Processes/Process_Manager_Death.cpp b/examples/APG/Processes/Process_Manager_Death.cpp
new file mode 100644
index 00000000000..38a49a77498
--- /dev/null
+++ b/examples/APG/Processes/Process_Manager_Death.cpp
@@ -0,0 +1,66 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Process_Manager.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/examples/APG/Processes/Process_Manager_Spawn.cpp b/examples/APG/Processes/Process_Manager_Spawn.cpp
new file mode 100644
index 00000000000..73b32f30c25
--- /dev/null
+++ b/examples/APG/Processes/Process_Manager_Spawn.cpp
@@ -0,0 +1,58 @@
+// $Id$
+
+#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/examples/APG/Processes/Process_Mutex.cpp b/examples/APG/Processes/Process_Mutex.cpp
new file mode 100644
index 00000000000..3d85426f5e7
--- /dev/null
+++ b/examples/APG/Processes/Process_Mutex.cpp
@@ -0,0 +1,78 @@
+// $Id$
+
+#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 ("%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/examples/APG/Processes/Spawn.cpp b/examples/APG/Processes/Spawn.cpp
new file mode 100644
index 00000000000..4f2df2609de
--- /dev/null
+++ b/examples/APG/Processes/Spawn.cpp
@@ -0,0 +1,197 @@
+// $Id$
+
+#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 (ACE_TEXT ("Manager::Manager"));
+ ACE_OS::strcpy (programName_, program_name);
+ }
+
+ int doWork (void)
+ {
+ ACE_TRACE (ACE_TEXT ("Manager::doWork"));
+
+ // Spawn the new process; prepare() hook is called first.
+ ACE_Process_Options options;
+ pid_t pid = this->spawn (options);
+ if (pid == -1)
+ 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 (ACE_TEXT ("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];
+ int 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 (ACE_TEXT ("Manager::prepare"));
+
+ options.command_line ("%s 1", this->programName_);
+ if (this->setStdHandles (options) == -1 ||
+ this->setEnvVariable (options) == -1)
+ return -1;
+#if !defined (ACE_WIN32)
+ return this->setUserID (options);
+#else
+ return 0;
+#endif
+ }
+
+ int setStdHandles (ACE_Process_Options &options)
+ {
+ ACE_TRACE(ACE_TEXT ("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 (ACE_TEXT ("Manager::setEnvVariables"));
+ return options.setenv ("PRIVATE_VAR=/that/seems/to/be/it");
+ }
+ // Listing 2
+
+#if !defined (ACE_WIN32)
+ // Listing 10 code/ch10
+ int setUserID (ACE_Process_Options &options)
+ {
+ ACE_TRACE (ACE_TEXT ("Manager::setUserID"));
+ passwd* pw = ACE_OS::getpwnam ("nobody");
+ if (pw == 0)
+ return -1;
+ options.seteuid (pw->pw_uid);
+ return 0;
+ }
+ // Listing 10
+#endif /* ACE_WIN32 */
+
+private:
+ ACE_HANDLE outputfd_;
+ ACE_TCHAR programName_[256];
+};
+
+// Listing 4 code/ch10
+class Slave
+{
+public:
+ Slave ()
+ {
+ ACE_TRACE (ACE_TEXT ("Slave::Slave"));
+ }
+
+ int doWork (void)
+ {
+ ACE_TRACE (ACE_TEXT ("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"),
+ 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 (ACE_TEXT ("Slave::showWho"));
+#if !defined (ACE_WIN32)
+ 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 (ACE_TEXT ("Slave::readLine"));
+
+ int i = 0;
+ while (true)
+ {
+ int 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/examples/APG/Processes/processes.mpc b/examples/APG/Processes/processes.mpc
new file mode 100644
index 00000000000..bfc816096de
--- /dev/null
+++ b/examples/APG/Processes/processes.mpc
@@ -0,0 +1,27 @@
+project(Process Manager Death) : aceexe {
+ exename = Process_Manager_Death
+ Source_Files {
+ Process_Manager_Death.cpp
+ }
+}
+
+project(Process Manager Spawn) : aceexe {
+ exename = Process_Manager_Spawn
+ Source_Files {
+ Process_Manager_Spawn.cpp
+ }
+}
+
+project(Process Mutex) : aceexe {
+ exename = Process_Mutex
+ Source_Files {
+ Process_Mutex.cpp
+ }
+}
+
+project(Spawn) : aceexe {
+ exename = Spawn
+ Source_Files {
+ Spawn.cpp
+ }
+}
diff --git a/examples/APG/Processes/processes.mwc b/examples/APG/Processes/processes.mwc
new file mode 100644
index 00000000000..6954a984564
--- /dev/null
+++ b/examples/APG/Processes/processes.mwc
@@ -0,0 +1,3 @@
+workspace {
+ processes.mpc
+}
diff --git a/examples/APG/Reactor/Client.cpp b/examples/APG/Reactor/Client.cpp
new file mode 100644
index 00000000000..cd60378870a
--- /dev/null
+++ b/examples/APG/Reactor/Client.cpp
@@ -0,0 +1,118 @@
+/**
+ * $Id$
+ *
+ * A simple client program using ACE_Svc_Handler and ACE_Connector.
+ */
+
+#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_);
+ 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"),
+ ACE_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;
+ char msg[128];
+ ACE_OS::sprintf (msg, "Iteration %d\n", this->iterations_);
+ ACE_NEW_RETURN (mb, ACE_Message_Block (msg), -1);
+ 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 (ACE_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 ("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
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Connector<Client, ACE_SOCK_CONNECTOR>;
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+# pragma instantiate ACE_Connector<Client, ACE_SOCK_CONNECTOR>
+# pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+// Listing 7
diff --git a/examples/APG/Reactor/Client.h b/examples/APG/Reactor/Client.h
new file mode 100644
index 00000000000..956ae566eaa
--- /dev/null
+++ b/examples/APG/Reactor/Client.h
@@ -0,0 +1,48 @@
+/**
+ * $Id$
+ *
+ * Sample code from The ACE Programmer's Guide,
+ * copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#ifndef __CLIENT_H_
+#define __CLIENT_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 &current_time,
+ const void *act = 0);
+
+private:
+ enum { ITERATIONS = 5 };
+ int iterations_;
+ ACE_Reactor_Notification_Strategy notifier_;
+};
+// Listing 1
+
+#endif /* __CLIENT_H_ */
diff --git a/examples/APG/Reactor/ClientService.h b/examples/APG/Reactor/ClientService.h
new file mode 100644
index 00000000000..55b75e19b61
--- /dev/null
+++ b/examples/APG/Reactor/ClientService.h
@@ -0,0 +1,36 @@
+/**
+ * $Id$
+ *
+ * Sample code from The ACE Programmer's Guide,
+ * copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#ifndef __CLIENTSERVICE_H_
+#define __CLIENTSERVICE_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/examples/APG/Reactor/HAStatus-AC.cpp b/examples/APG/Reactor/HAStatus-AC.cpp
new file mode 100644
index 00000000000..27220a22718
--- /dev/null
+++ b/examples/APG/Reactor/HAStatus-AC.cpp
@@ -0,0 +1,144 @@
+// $Id$
+
+#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,
+ ACE_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 =
+ ACE_static_cast (size_t, (recv_cnt - send_cnt));
+ ACE_NEW_RETURN
+ (mb, ACE_Message_Block (&buffer[send_cnt], remaining), -1);
+ 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 (ACE_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
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR>;
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR>
+#pragma instantiate \
+ ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+// Listing 8
diff --git a/examples/APG/Reactor/HAStatus.cpp b/examples/APG/Reactor/HAStatus.cpp
new file mode 100644
index 00000000000..bba4c73dbc6
--- /dev/null
+++ b/examples/APG/Reactor/HAStatus.cpp
@@ -0,0 +1,326 @@
+// $Id$
+
+// 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"
+
+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, ACE_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 =
+ ACE_static_cast (size_t, (recv_cnt - send_cnt));
+ ACE_NEW_RETURN
+ (mb, ACE_Message_Block (&buffer[send_cnt], remaining), -1);
+ 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 (ACE_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
+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/examples/APG/Reactor/Makefile b/examples/APG/Reactor/Makefile
new file mode 100644
index 00000000000..677177c34ff
--- /dev/null
+++ b/examples/APG/Reactor/Makefile
@@ -0,0 +1,27 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+# Makefile for Reactor-based examples
+
+BIN = Client \
+ HAStatus \
+ HAStatus-AC \
+ Reschedule \
+ Schedule_Timers \
+ Timer_Cancel \
+ Timers \
+ Timer_State_Data
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/Reactor/Reschedule.cpp b/examples/APG/Reactor/Reschedule.cpp
new file mode 100644
index 00000000000..79196354729
--- /dev/null
+++ b/examples/APG/Reactor/Reschedule.cpp
@@ -0,0 +1,82 @@
+/**
+ * $Id$
+ *
+ * Changing the interval
+ */
+
+#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 &current_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/examples/APG/Reactor/Schedule_Timers.cpp b/examples/APG/Reactor/Schedule_Timers.cpp
new file mode 100644
index 00000000000..40482f9f233
--- /dev/null
+++ b/examples/APG/Reactor/Schedule_Timers.cpp
@@ -0,0 +1,64 @@
+/**
+ * $Id$
+ *
+ * Scheduling timers with the Reactor
+ */
+
+#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 &current_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/examples/APG/Reactor/Timer_Cancel.cpp b/examples/APG/Reactor/Timer_Cancel.cpp
new file mode 100644
index 00000000000..39f15e459b7
--- /dev/null
+++ b/examples/APG/Reactor/Timer_Cancel.cpp
@@ -0,0 +1,103 @@
+/**
+ * $Id$
+ *
+ * Changing the interval and canceling
+ */
+
+#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 &current_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
+
+#endif /* ACE_LACKS_UNIX_SIGNALS */
+
+ ACE_Reactor::instance ()->run_reactor_event_loop ();
+ return 0;
+}
diff --git a/examples/APG/Reactor/Timer_State_Data.cpp b/examples/APG/Reactor/Timer_State_Data.cpp
new file mode 100644
index 00000000000..4ccb9f6f677
--- /dev/null
+++ b/examples/APG/Reactor/Timer_State_Data.cpp
@@ -0,0 +1,152 @@
+/**
+ * $Id$
+ *
+ * Reactor examples
+ *
+ * Timers & state data
+ */
+
+#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 &current_time,
+ const void *arg)
+ {
+ time_t epoch = ((timespec_t)current_time).tv_sec;
+
+ const TemperatureSensor *const_sensor =
+ ACE_reinterpret_cast (const TemperatureSensor *, arg);
+ TemperatureSensor *sensor =
+ ACE_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 *sensor)
+ {
+ // ...
+ }
+
+ 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/examples/APG/Reactor/Timers.cpp b/examples/APG/Reactor/Timers.cpp
new file mode 100644
index 00000000000..bc17e3aa202
--- /dev/null
+++ b/examples/APG/Reactor/Timers.cpp
@@ -0,0 +1,79 @@
+// $Id$
+
+#include "ace/config.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);
+ }
+
+ 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 main (int, char *[])
+{
+ pid_t timerId = timerTask (3, 5, foo);
+ programMainLoop ();
+ kill (timerId, SIGINT);
+ return 0;
+}
+// Listing 3
+
+#else
+#include <stdio.h>
+
+int main (int, char *[])
+{
+ puts ("This very unportable example requires fork().\n");
+ return 0;
+}
+
+#endif /* ACE_LACKS_FORK */
diff --git a/examples/APG/Reactor/reactor.mpc b/examples/APG/Reactor/reactor.mpc
new file mode 100644
index 00000000000..6f93acedd68
--- /dev/null
+++ b/examples/APG/Reactor/reactor.mpc
@@ -0,0 +1,55 @@
+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/examples/APG/Reactor/reactor.mwc b/examples/APG/Reactor/reactor.mwc
new file mode 100644
index 00000000000..d8629c9f435
--- /dev/null
+++ b/examples/APG/Reactor/reactor.mwc
@@ -0,0 +1,3 @@
+workspace {
+ reactor.mpc
+}
diff --git a/examples/APG/Shared_Memory/Hash_Map.cpp b/examples/APG/Shared_Memory/Hash_Map.cpp
new file mode 100644
index 00000000000..1ac1d4501ea
--- /dev/null
+++ b/examples/APG/Shared_Memory/Hash_Map.cpp
@@ -0,0 +1,257 @@
+// $Id$
+
+// Listing 1 code/ch17
+#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> MAP;
+
+ACE_Process_Mutex coordMutex("Coord-Mutex");
+// Listing 1
+
+// Listing 2 code/ch17
+MAP* smap (ALLOCATOR *shmem_allocator)
+{
+ void *db = 0;
+ if (shmem_allocator->find (MAP_NAME, db) == 0)
+ return (MAP *) db;
+ size_t hash_table_size = sizeof (MAP);
+ void *hash_map = shmem_allocator->malloc (hash_table_size);
+ if (hash_map == 0)
+ return 0;
+ new (hash_map) 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 (MAP*)hash_map;
+}
+// Listing 2
+// Listing 6 code/ch17
+int processRecords (MAP *map, ALLOCATOR *shmem_allocator)
+{
+ ACE_TRACE (ACE_TEXT ("::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 (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(MAP *map, ALLOCATOR *shmem_allocator)
+{
+ ACE_TRACE (ACE_TEXT ("::addRecords"));
+
+ char buf[32];
+ int mapLength = ACE_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 (ACE_TEXT ("::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);
+
+ 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 (char *cmdLine)
+{
+ ACE_TRACE (ACE_TEXT ("::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);
+
+ MAP *map = smap (shmem_allocator);
+
+ ACE_Process processa, processb;
+ ACE_Process_Options poptions;
+ poptions.command_line("%s a", cmdLine);
+ {
+ 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);
+
+ return 0;
+}
+// Listing 3
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+// The following instantiation is in ace/System_Time.cpp:
+// template class ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+template class ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+// The following instantiation is in ace/System_Time.cpp:
+// #pragma instantiate ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#pragma instantiate ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Shared_Memory/Makefile b/examples/APG/Shared_Memory/Makefile
new file mode 100644
index 00000000000..da92484d68c
--- /dev/null
+++ b/examples/APG/Shared_Memory/Makefile
@@ -0,0 +1,21 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Hash_Map Malloc Mem_Map PI_Malloc Pool_Growth
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/Shared_Memory/Malloc.cpp b/examples/APG/Shared_Memory/Malloc.cpp
new file mode 100644
index 00000000000..40fc582dd30
--- /dev/null
+++ b/examples/APG/Shared_Memory/Malloc.cpp
@@ -0,0 +1,124 @@
+// $Id$
+
+// Listing 1 code/ch17
+#include "ace/Malloc_T.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_ =
+ ACE_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 =
+ ACE_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 "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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+// The following instantiation is in ace/System_Time.cpp:
+// template class ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+template class ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+// The following instantiation is in ace/System_Time.cpp:
+// #pragma instantiate ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#pragma instantiate ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Shared_Memory/Mem_Map.cpp b/examples/APG/Shared_Memory/Mem_Map.cpp
new file mode 100644
index 00000000000..c70019deb6c
--- /dev/null
+++ b/examples/APG/Shared_Memory/Mem_Map.cpp
@@ -0,0 +1,34 @@
+// $Id$
+
+#include "ace/OS.h"
+#include "ace/Mem_Map.h"
+#include "ace/Log_Msg.h"
+
+// Listing 1 code/ch17
+int ACE_TMAIN (int argc, 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/examples/APG/Shared_Memory/PI_Malloc.cpp b/examples/APG/Shared_Memory/PI_Malloc.cpp
new file mode 100644
index 00000000000..e067b5503dc
--- /dev/null
+++ b/examples/APG/Shared_Memory/PI_Malloc.cpp
@@ -0,0 +1,146 @@
+// $Id$
+
+// Listing 1 code/ch17
+#include "ace/Malloc_T.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 =
+ ACE_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 =
+ ACE_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 "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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Malloc_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>;
+template class ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>;
+template class ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Malloc_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>
+#pragma instantiate ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>
+#pragma instantiate ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
diff --git a/examples/APG/Shared_Memory/Pool_Growth.cpp b/examples/APG/Shared_Memory/Pool_Growth.cpp
new file mode 100644
index 00000000000..6125a8f9dd9
--- /dev/null
+++ b/examples/APG/Shared_Memory/Pool_Growth.cpp
@@ -0,0 +1,269 @@
+// $Id$
+
+#include "ace/Containers_T.h"
+#include "ace/Malloc.h"
+#include "ace/PI_Malloc.h"
+#include "ace/Process_Mutex.h"
+#include "ace/Process.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 (char *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;
+ poptions.command_line ("%s a", ACE_TEXT_ALWAYS_CHAR (cmdLine));
+ 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;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+// The following instantiation is in ace/System_Time.cpp:
+// template class ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>;
+template class ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+template class ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+// The following instantiation is in ace/System_Time.cpp:
+// #pragma instantiate ACE_Malloc <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_LIFO_Iterator <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex>
+#pragma instantiate ACE_Malloc_FIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#pragma instantiate ACE_Malloc_LIFO_Iterator_T <ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_Control_Block>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Shared_Memory/Record.h b/examples/APG/Shared_Memory/Record.h
new file mode 100644
index 00000000000..c71f8d9ad74
--- /dev/null
+++ b/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.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/examples/APG/Shared_Memory/shared_memory.mpc b/examples/APG/Shared_Memory/shared_memory.mpc
new file mode 100644
index 00000000000..0f7fefb0dd0
--- /dev/null
+++ b/examples/APG/Shared_Memory/shared_memory.mpc
@@ -0,0 +1,34 @@
+project(Hash Map) : aceexe {
+ exename = Hash_Map
+ Source_Files {
+ Hash_Map.cpp
+ }
+}
+
+project(Malloc) : aceexe {
+ exename = Malloc
+ Source_Files {
+ Malloc.cpp
+ }
+}
+
+project(Mem Map) : aceexe {
+ exename = Mem_Map
+ Source_Files {
+ Mem_Map.cpp
+ }
+}
+
+project(PI Malloc) : aceexe {
+ exename = PI_Malloc
+ Source_Files {
+ PI_Malloc.cpp
+ }
+}
+
+project(Pool Growth) : aceexe {
+ exename = Pool_Growth
+ Source_Files {
+ Pool_Growth.cpp
+ }
+}
diff --git a/examples/APG/Shared_Memory/shared_memory.mwc b/examples/APG/Shared_Memory/shared_memory.mwc
new file mode 100644
index 00000000000..1e352092a8c
--- /dev/null
+++ b/examples/APG/Shared_Memory/shared_memory.mwc
@@ -0,0 +1,3 @@
+workspace {
+ shared_memory.mpc
+}
diff --git a/examples/APG/Signals/Makefile b/examples/APG/Signals/Makefile
new file mode 100644
index 00000000000..acdd1bd39e3
--- /dev/null
+++ b/examples/APG/Signals/Makefile
@@ -0,0 +1,18 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = SigAction \
+ SigGuard \
+ SigHandler \
+ SigHandlers \
+ SigInfo
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Signals/SigAction.cpp b/examples/APG/Signals/SigAction.cpp
new file mode 100644
index 00000000000..90f59e04e69
--- /dev/null
+++ b/examples/APG/Signals/SigAction.cpp
@@ -0,0 +1,68 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+// Listing 1 code/ch11
+#include "ace/Signal.h"
+
+// Forward declarations.
+static void my_sighandler (int signo);
+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
+// 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);
+}
+// Listing 3
+// Listing 2 code/ch11
+static void register_actions ()
+{
+ ACE_TRACE (ACE_TEXT ("::register_actions"));
+
+ ACE_Sig_Action sa (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/examples/APG/Signals/SigGuard.cpp b/examples/APG/Signals/SigGuard.cpp
new file mode 100644
index 00000000000..13232fb97ff
--- /dev/null
+++ b/examples/APG/Signals/SigGuard.cpp
@@ -0,0 +1,41 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Signal.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/examples/APG/Signals/SigHandler.cpp b/examples/APG/Signals/SigHandler.cpp
new file mode 100644
index 00000000000..103d556f08d
--- /dev/null
+++ b/examples/APG/Signals/SigHandler.cpp
@@ -0,0 +1,58 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Signal.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/examples/APG/Signals/SigHandlers.cpp b/examples/APG/Signals/SigHandlers.cpp
new file mode 100644
index 00000000000..9195903c88e
--- /dev/null
+++ b/examples/APG/Signals/SigHandlers.cpp
@@ -0,0 +1,52 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Signal.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/examples/APG/Signals/SigInfo.cpp b/examples/APG/Signals/SigInfo.cpp
new file mode 100644
index 00000000000..866e0022edb
--- /dev/null
+++ b/examples/APG/Signals/SigInfo.cpp
@@ -0,0 +1,149 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Reactor.h"
+#include "ace/Event_Handler.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,
+ 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 */
+
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+#if defined (ACE_LACKS_FORK)
+ puts ("This 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;
+}
diff --git a/examples/APG/Signals/signals.mpc b/examples/APG/Signals/signals.mpc
new file mode 100644
index 00000000000..4eaa58375da
--- /dev/null
+++ b/examples/APG/Signals/signals.mpc
@@ -0,0 +1,34 @@
+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/examples/APG/Signals/signals.mwc b/examples/APG/Signals/signals.mwc
new file mode 100644
index 00000000000..8322d188d6d
--- /dev/null
+++ b/examples/APG/Signals/signals.mwc
@@ -0,0 +1,3 @@
+workspace {
+ signals.mpc
+}
diff --git a/examples/APG/Sockets/Basic.cpp b/examples/APG/Sockets/Basic.cpp
new file mode 100644
index 00000000000..d517a430b0a
--- /dev/null
+++ b/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
+
+ int 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/examples/APG/Sockets/Basic_Robust.cpp b/examples/APG/Sockets/Basic_Robust.cpp
new file mode 100644
index 00000000000..a3687abf571
--- /dev/null
+++ b/examples/APG/Sockets/Basic_Robust.cpp
@@ -0,0 +1,135 @@
+// $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 *[])
+{
+ /*
+ * 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 ("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 ("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/examples/APG/Sockets/Iovec.cpp b/examples/APG/Sockets/Iovec.cpp
new file mode 100644
index 00000000000..ad957c74af8
--- /dev/null
+++ b/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 = ACE_const_cast (ACE_TCHAR *, "up");
+ send[0].iov_len = 2;
+ send[1].iov_base = ACE_const_cast (ACE_TCHAR *, "time");
+ send[1].iov_len = 4;
+ send[2].iov_base = ACE_const_cast (ACE_TCHAR *, "\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 (ACE_static_cast (size_t, bc) < wc)
+ wc = ACE_static_cast (size_t, bc);
+ write (1, receive[i].iov_base, wc);
+ bc -= receive[i].iov_len;
+ delete []
+ (ACE_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 [] ACE_reinterpret_cast (char *, response.iov_base);
+ // Listing 5
+
+ peer.close ();
+
+ return (0);
+}
diff --git a/examples/APG/Sockets/Makefile b/examples/APG/Sockets/Makefile
new file mode 100644
index 00000000000..6a21c53c460
--- /dev/null
+++ b/examples/APG/Sockets/Makefile
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Basic Basic_Robust Iovec Server
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Sockets/Server.cpp b/examples/APG/Sockets/Server.cpp
new file mode 100644
index 00000000000..11d058cf97a
--- /dev/null
+++ b/examples/APG/Sockets/Server.cpp
@@ -0,0 +1,92 @@
+// $Id$
+
+#include "ace/INET_Addr.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/SOCK_Acceptor.h"
+#include "ace/Log_Msg.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
+ }
+ }
+
+ return (0);
+}
diff --git a/examples/APG/Sockets/sockets.mpc b/examples/APG/Sockets/sockets.mpc
new file mode 100644
index 00000000000..49e45bf9f88
--- /dev/null
+++ b/examples/APG/Sockets/sockets.mpc
@@ -0,0 +1,27 @@
+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/examples/APG/Sockets/sockets.mwc b/examples/APG/Sockets/sockets.mwc
new file mode 100644
index 00000000000..48e1c08afdc
--- /dev/null
+++ b/examples/APG/Sockets/sockets.mwc
@@ -0,0 +1,3 @@
+workspace {
+ sockets.mpc
+}
diff --git a/examples/APG/Streams/Answerer.cpp b/examples/APG/Streams/Answerer.cpp
new file mode 100644
index 00000000000..dbb5ab4f2dd
--- /dev/null
+++ b/examples/APG/Streams/Answerer.cpp
@@ -0,0 +1,411 @@
+/**
+ * $Id$
+ *
+ * Streams Listing 01
+ *
+ * An answering machine based on a one-way ACE_Stream
+ */
+
+#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 *message)
+ {
+ // Exclude 23
+ return ACE_FILE_Addr ("/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 ("/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 *message)
+ {
+ // Exclude 26
+ return ACE_FILE_Addr ("/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_CString path (message->addr ().get_path_name ());
+ path += ".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
+ int open (void)
+ {
+ Module *endModule;
+ ACE_NEW_RETURN (endModule,
+ Module ("End Module", new EndTask ()),
+ -1);
+ this->inherited::open ((void *)0, (Module *)0, endModule);
+ // Listing 1000
+
+ // Listing 1001 code/ch18
+ Module *answerIncomingCallModule;
+ ACE_NEW_RETURN (answerIncomingCallModule,
+ Module ("Answer Incoming Call",
+ new AnswerIncomingCall ()),
+ -1);
+
+ // Listing 11 code/ch18
+ Module *getCallerIdModule;
+ ACE_NEW_RETURN (getCallerIdModule,
+ Module ("Get Caller ID", new GetCallerId ()),
+ -1);
+ // Listing 11
+
+ Module *playOGMModule;
+ ACE_NEW_RETURN (playOGMModule,
+ Module ("Play Outgoing Message",
+ new PlayOutgoingMessage ()),
+ -1);
+
+ Module *recordModule;
+ ACE_NEW_RETURN (recordModule,
+ Module ("Record Incoming Message",
+ new RecordIncomingMessage ()),
+ -1);
+
+ Module *releaseModule;
+ ACE_NEW_RETURN (releaseModule,
+ Module ("Release Device",
+ new ReleaseDevice ()),
+ -1);
+
+ Module *conversionModule;
+ ACE_NEW_RETURN (conversionModule,
+ Module ("Encode Message",
+ new EncodeMessage ()),
+ -1);
+
+ Module *saveMetaDataModule;
+ ACE_NEW_RETURN (saveMetaDataModule,
+ Module ("Save Meta-Data",
+ new SaveMetaData ()),
+ -1);
+
+ Module *notificationModule;
+ ACE_NEW_RETURN (notificationModule,
+ Module ("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)
+ 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;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_IOStream<FILE_IO_Adaptor>
+;
+template class ACE_Streambuf_T<FILE_IO_Adaptor>
+;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate class ACE_IOStream<FILE_IO_Adaptor>;
+#pragma instantiate class ACE_Streambuf_T<FILE_IO_Adaptor>;
+#endif
diff --git a/examples/APG/Streams/BasicTask.h b/examples/APG/Streams/BasicTask.h
new file mode 100644
index 00000000000..86ac180925f
--- /dev/null
+++ b/examples/APG/Streams/BasicTask.h
@@ -0,0 +1,144 @@
+/* -*- 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->duplicate ()) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Task::svc() putq")),
+ -1);
+ }
+ 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->duplicate ()) < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("put_next failed")),
+ -1);
+
+ message->release ();
+ // 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->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 103
+
+ // Listing 105 code/ch18
+protected:
+ virtual int next_step (ACE_Message_Block *message_block)
+ {
+ return this->put_next (message_block->duplicate ());
+ }
+ // 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/examples/APG/Streams/Command.h b/examples/APG/Streams/Command.h
new file mode 100644
index 00000000000..1ce5c866507
--- /dev/null
+++ b/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 {
+ PASS = 1,
+ SUCCESS = 0,
+ FAILURE = -1
+ };
+
+ // Commands
+ enum {
+ UNKNOWN = -1,
+ ANSWER_CALL = 10,
+ RETRIEVE_CALLER_ID,
+ PLAY_MESSAGE,
+ RECORD_MESSAGE
+ } commands;
+
+ int flags_;
+ int command_;
+
+ void *extra_data_;
+
+ int numeric_result_;
+ ACE_CString result_;
+};
+// Listing 01
+
+#endif /* COMMAND_H */
diff --git a/examples/APG/Streams/CommandModule.cpp b/examples/APG/Streams/CommandModule.cpp
new file mode 100644
index 00000000000..9ee5a92918a
--- /dev/null
+++ b/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/examples/APG/Streams/CommandModule.h b/examples/APG/Streams/CommandModule.h
new file mode 100644
index 00000000000..7fe65b81f78
--- /dev/null
+++ b/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/examples/APG/Streams/CommandStream.cpp b/examples/APG/Streams/CommandStream.cpp
new file mode 100644
index 00000000000..e31afd25020
--- /dev/null
+++ b/examples/APG/Streams/CommandStream.cpp
@@ -0,0 +1,91 @@
+// $Id$
+
+#include "CommandStream.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 (ACE_SOCK_Stream *peer)
+{
+ ACE_TRACE (ACE_TEXT ("CommandStream::open(peer)"));
+
+ if (this->inherited::open (0) == -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 (peer),
+ -1);
+
+ CommandModule *retrieveCallerIdModule;
+ ACE_NEW_RETURN (retrieveCallerIdModule,
+ RetrieveCallerIdModule (peer),
+ -1);
+
+ CommandModule *playMessageModule;
+ ACE_NEW_RETURN (playMessageModule,
+ PlayMessageModule (peer),
+ -1);
+
+ CommandModule *recordMessageModule;
+ ACE_NEW_RETURN (recordMessageModule,
+ RecordMessageModule (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"),
+ ACE_TEXT (answerCallModule->name())),
+ -1);
+
+ if (this->push (retrieveCallerIdModule) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Failed to push %p\n"),
+ ACE_TEXT (retrieveCallerIdModule->name())),
+ -1);
+
+ if (this->push (playMessageModule) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Failed to push %p\n"),
+ ACE_TEXT (playMessageModule->name())),
+ -1);
+
+ if (this->push (recordMessageModule) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Failed to push %p\n"),
+ ACE_TEXT (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/examples/APG/Streams/CommandStream.h b/examples/APG/Streams/CommandStream.h
new file mode 100644
index 00000000000..a8406436a76
--- /dev/null
+++ b/examples/APG/Streams/CommandStream.h
@@ -0,0 +1,34 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef COMMAND_STREAM_H
+#define COMMAND_STREAM_H
+
+#include "ace/Module.h"
+#include "ace/Stream.h"
+#include "ace/SOCK_Stream.h"
+
+#include "Command.h"
+#include "CommandTasks.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 () : inherited() { }
+ int open (ACE_SOCK_Stream *peer);
+ Command *execute (Command *command);
+};
+// Listing 01
+
+#endif /* COMMAND_STREAM_H */
diff --git a/examples/APG/Streams/CommandTask.cpp b/examples/APG/Streams/CommandTask.cpp
new file mode 100644
index 00000000000..734ba39c445
--- /dev/null
+++ b/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::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"),
+ ACE_TEXT (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"),
+ ACE_TEXT (this->module ()->name ()),
+ command->command_,
+ result));
+
+ if (result == Command::FAILURE)
+ {
+ command->numeric_result_ = -1;
+ }
+ // Listing 063
+ // Listing 064 code/ch18
+ else if (result == Command::PASS)
+ {
+ this->put_next (message->duplicate ());
+ }
+ // Listing 064
+ // Listing 065 code/ch18
+ else // result == Command::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/examples/APG/Streams/CommandTask.h b/examples/APG/Streams/CommandTask.h
new file mode 100644
index 00000000000..ae78017b0f9
--- /dev/null
+++ b/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/examples/APG/Streams/CommandTasks.cpp b/examples/APG/Streams/CommandTasks.cpp
new file mode 100644
index 00000000000..a4910fb23d2
--- /dev/null
+++ b/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 ("AnswerCall Module",
+ new AnswerCallDownstreamTask (),
+ new AnswerCallUpstreamTask (),
+ peer)
+{ }
+// Listing 011
+// Listing 012 code/ch18
+AnswerCallDownstreamTask::AnswerCallDownstreamTask (void)
+ : CommandTask(Command::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::SUCCESS;
+}
+// Listing 013
+// Listing 014 code/ch18
+AnswerCallUpstreamTask::AnswerCallUpstreamTask (void)
+ : CommandTask(Command::ANSWER_CALL)
+{ }
+// Listing 014
+// Listing 015 code/ch18
+int AnswerCallUpstreamTask::process (Command *)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Answer Call (upstream)\n")));
+
+ return Command::SUCCESS;
+}
+// Listing 015
+
+// Listing 021 code/ch18
+RetrieveCallerIdModule::RetrieveCallerIdModule
+ (ACE_SOCK_Stream *peer)
+ : CommandModule ("RetrieveCallerId Module",
+ new RetrieveCallerIdDownstreamTask (),
+ new RetrieveCallerIdUpstreamTask (),
+ peer)
+{ }
+// Listing 021
+// Listing 022 code/ch18
+RetrieveCallerIdDownstreamTask::RetrieveCallerIdDownstreamTask
+ (void)
+ : CommandTask(Command::RETRIEVE_CALLER_ID)
+{ }
+
+int RetrieveCallerIdDownstreamTask::process (Command *)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Retrieving Caller ID data\n")));
+
+ return Command::SUCCESS;
+}
+// Listing 022
+// Listing 023 code/ch18
+RetrieveCallerIdUpstreamTask::RetrieveCallerIdUpstreamTask
+ (void)
+ : CommandTask(Command::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_CString (remote_addr_str);
+
+ return Command::SUCCESS;
+}
+// Listing 023
+
+PlayMessageModule::PlayMessageModule (ACE_SOCK_Stream *peer)
+ : CommandModule ("PlayMessage Module",
+ new PlayMessageDownstreamTask (),
+ new PlayMessageUpstreamTask (),
+ peer)
+{ }
+
+PlayMessageDownstreamTask::PlayMessageDownstreamTask (void)
+ : CommandTask(Command::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];
+ int rwbytes;
+ while ((rwbytes = file.recv (rwbuf, 512)) > 0)
+ {
+ module->peer ().send_n (rwbuf, rwbytes);
+ }
+ }
+
+ return Command::SUCCESS;
+}
+// Listing 032
+PlayMessageUpstreamTask::PlayMessageUpstreamTask (void)
+ : CommandTask(Command::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"),
+ ACE_TEXT (addr->get_path_name ())));
+
+ return Command::SUCCESS;
+}
+
+RecordMessageModule::RecordMessageModule (ACE_SOCK_Stream *peer)
+ : CommandModule ("RecordMessage Module",
+ new RecordMessageDownstreamTask (),
+ new RecordMessageUpstreamTask (),
+ peer)
+{ }
+
+RecordMessageDownstreamTask::RecordMessageDownstreamTask (void)
+ : CommandTask(Command::RECORD_MESSAGE)
+{ }
+
+int RecordMessageDownstreamTask::process (Command *)
+{
+ return Command::SUCCESS;
+}
+
+RecordMessageUpstreamTask::RecordMessageUpstreamTask (void)
+ : CommandTask(Command::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::FAILURE);
+ file.truncate (0);
+
+ CommandModule *module =
+ (CommandModule*)this->module ();
+
+ int total_bytes = 0;
+ char rwbuf[512];
+ int 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::SUCCESS;
+}
+// Listing 033
diff --git a/examples/APG/Streams/CommandTasks.h b/examples/APG/Streams/CommandTasks.h
new file mode 100644
index 00000000000..0d55d4da07b
--- /dev/null
+++ b/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/examples/APG/Streams/EndTask.h b/examples/APG/Streams/EndTask.h
new file mode 100644
index 00000000000..62b4093f975
--- /dev/null
+++ b/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 *)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("EndTask::next_step() - ")
+ ACE_TEXT ("end of the line.\n")));
+ return 0;
+ }
+};
+// Listing 1
+
+#endif /* END_TASK_H */
diff --git a/examples/APG/Streams/Makefile b/examples/APG/Streams/Makefile
new file mode 100644
index 00000000000..a12ee52b8d9
--- /dev/null
+++ b/examples/APG/Streams/Makefile
@@ -0,0 +1,24 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Answerer
+
+FILES = CommandModule \
+ CommandStream \
+ CommandTask \
+ CommandTasks \
+ RecordingDeviceFactory \
+ RecordingDevice_Text
+
+SRC = $(addsuffix .cpp,$(FILES))
+OBJ = $(addsuffix .o,$(FILES))
+
+BUILD = $(VBIN)
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Streams/Message.h b/examples/APG/Streams/Message.h
new file mode 100644
index 00000000000..29ddd30d5a1
--- /dev/null
+++ b/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/examples/APG/Streams/MessageInfo.h b/examples/APG/Streams/MessageInfo.h
new file mode 100644
index 00000000000..c609db608eb
--- /dev/null
+++ b/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_("UNKNOWN")
+ { }
+
+ CallerId (ACE_CString id) : id_(id)
+ { }
+
+ const char *string(void)
+ {
+ return this->id_.c_str ();
+ }
+
+private:
+ ACE_CString 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/examples/APG/Streams/RecordingDevice.h b/examples/APG/Streams/RecordingDevice.h
new file mode 100644
index 00000000000..4672aa500fb
--- /dev/null
+++ b/examples/APG/Streams/RecordingDevice.h
@@ -0,0 +1,118 @@
+/* -*- 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"
+
+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/examples/APG/Streams/RecordingDeviceFactory.cpp b/examples/APG/Streams/RecordingDeviceFactory.cpp
new file mode 100644
index 00000000000..f5585e1ec0a
--- /dev/null
+++ b/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/examples/APG/Streams/RecordingDeviceFactory.h b/examples/APG/Streams/RecordingDeviceFactory.h
new file mode 100644
index 00000000000..13485b20947
--- /dev/null
+++ b/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/examples/APG/Streams/RecordingDevice_QC.h b/examples/APG/Streams/RecordingDevice_QC.h
new file mode 100644
index 00000000000..356d70afc5c
--- /dev/null
+++ b/examples/APG/Streams/RecordingDevice_QC.h
@@ -0,0 +1,5 @@
+// $Id$
+
+class QuickCam : public RecordingDevice
+ {
+ };
diff --git a/examples/APG/Streams/RecordingDevice_Text.cpp b/examples/APG/Streams/RecordingDevice_Text.cpp
new file mode 100644
index 00000000000..5960c4607d9
--- /dev/null
+++ b/examples/APG/Streams/RecordingDevice_Text.cpp
@@ -0,0 +1,200 @@
+/*
+ * $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 (ACE_TEXT ("TextListener ctor"));
+
+ ACE_NEW (this->command_stream_, CommandStream ());
+ this->command_stream_->open (&(this->peer_));
+}
+// 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::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::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::PLAY_MESSAGE;
+ c->extra_data_ = &addr;
+
+ c = this->command_stream_->execute (c);
+ return c->numeric_result_;
+ }
+
+ ACE_FILE_Addr temp ("/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);
+
+ 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::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/examples/APG/Streams/RecordingDevice_Text.h b/examples/APG/Streams/RecordingDevice_Text.h
new file mode 100644
index 00000000000..a49f400d922
--- /dev/null
+++ b/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/examples/APG/Streams/RecordingDevice_USRVM.h b/examples/APG/Streams/RecordingDevice_USRVM.h
new file mode 100644
index 00000000000..7519f7c1c84
--- /dev/null
+++ b/examples/APG/Streams/RecordingDevice_USRVM.h
@@ -0,0 +1,5 @@
+// $Id$
+
+class USRoboticsVoiceModem : public RecordingDevice
+ {
+ };
diff --git a/examples/APG/Streams/Util.h b/examples/APG/Streams/Util.h
new file mode 100644
index 00000000000..fde8d05e6f1
--- /dev/null
+++ b/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 &src, 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 &src, 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];
+ int 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 &src, ACE_FILE_Addr &dest)
+ {
+ // Convert arbitrary audio data to some standard mp3 format
+ return 0;
+ }
+
+ static int convert_to_mpeg (ACE_FILE_Addr &src, ACE_FILE_Addr &dest)
+ {
+ // Convert arbitrary vidio data to some standard mpeg format
+ return 0;
+ }
+};
+
+#endif /* UTIL_H */
diff --git a/examples/APG/Streams/streams.mpc b/examples/APG/Streams/streams.mpc
new file mode 100644
index 00000000000..9868b7bcbb0
--- /dev/null
+++ b/examples/APG/Streams/streams.mpc
@@ -0,0 +1,12 @@
+project(Answerer) : aceexe {
+ exename = Answerer
+ Source_Files {
+ Answerer.cpp
+ CommandModule.cpp
+ CommandStream.cpp
+ CommandTask.cpp
+ CommandTasks.cpp
+ RecordingDeviceFactory.cpp
+ RecordingDevice_Text.cpp
+ }
+}
diff --git a/examples/APG/Streams/streams.mwc b/examples/APG/Streams/streams.mwc
new file mode 100644
index 00000000000..eab619b3bb1
--- /dev/null
+++ b/examples/APG/Streams/streams.mwc
@@ -0,0 +1,3 @@
+workspace {
+ streams.mpc
+}
diff --git a/examples/APG/Svc_Config/HASTATUS_export.h b/examples/APG/Svc_Config/HASTATUS_export.h
new file mode 100644
index 00000000000..b6aa4ad83b7
--- /dev/null
+++ b/examples/APG/Svc_Config/HASTATUS_export.h
@@ -0,0 +1,49 @@
+// -*- 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 (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/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp b/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp
new file mode 100644
index 00000000000..249c49cdb91
--- /dev/null
+++ b/examples/APG/Svc_Config/HA_Configurable_Server_Dynamic.cpp
@@ -0,0 +1,14 @@
+// $Id$
+
+// Listing 1 code/ch19
+#include "ace/OS.h"
+#include "ace/Service_Config.h"
+#include "ace/Reactor.h"
+
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Service_Config::open (argc, argv);
+ ACE_Reactor::instance ()->run_reactor_event_loop ();
+ return 0;
+}
+// Listing 1
diff --git a/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp b/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp
new file mode 100644
index 00000000000..a647618c701
--- /dev/null
+++ b/examples/APG/Svc_Config/HA_Configurable_Server_Static.cpp
@@ -0,0 +1,18 @@
+// $Id$
+
+// Listing 1 code/ch19
+#include "ace/OS.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/examples/APG/Svc_Config/HA_Status_Dynamic.cpp b/examples/APG/Svc_Config/HA_Status_Dynamic.cpp
new file mode 100644
index 00000000000..5d9ec185b23
--- /dev/null
+++ b/examples/APG/Svc_Config/HA_Status_Dynamic.cpp
@@ -0,0 +1,119 @@
+/**
+ * $Id$
+ *
+ * Home Automation Status server. Sample code from The ACE Programmer's Guide,
+ * Copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#include "ace/OS.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_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_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 (ACE_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_String::strncpy (*str, buf, len);
+ return ACE_static_cast (int, ACE_OS::strlen (*str));
+ }
+// Listing 3
+
+// Listing 4 code/ch19
+ACE_FACTORY_DEFINE (HASTATUS, HA_Status)
+// Listing 4
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+template class ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+# pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+# pragma instantiate ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Svc_Config/HA_Status_Dynamic.h b/examples/APG/Svc_Config/HA_Status_Dynamic.h
new file mode 100644
index 00000000000..c11f9a56d35
--- /dev/null
+++ b/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/examples/APG/Svc_Config/HA_Status_Static.cpp b/examples/APG/Svc_Config/HA_Status_Static.cpp
new file mode 100644
index 00000000000..5c2099db160
--- /dev/null
+++ b/examples/APG/Svc_Config/HA_Status_Static.cpp
@@ -0,0 +1,127 @@
+/**
+ * $Id$
+ *
+ * Home Automation Status server. Sample code from The ACE Programmer's Guide,
+ * Copyright 2003 Addison-Wesley. All Rights Reserved.
+ */
+
+#include "ace/OS.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_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_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 (ACE_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_String::strncpy (*str, buf, len);
+ return ACE_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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+template class ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+# pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+# pragma instantiate ACE_Acceptor<ClientHandler, ACE_SOCK_ACCEPTOR>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/Svc_Config/HA_Status_Static.h b/examples/APG/Svc_Config/HA_Status_Static.h
new file mode 100644
index 00000000000..6545cdadf48
--- /dev/null
+++ b/examples/APG/Svc_Config/HA_Status_Static.h
@@ -0,0 +1,39 @@
+/**
+ * $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"
+
+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/examples/APG/Svc_Config/Makefile b/examples/APG/Svc_Config/Makefile
new file mode 100644
index 00000000000..4400726a162
--- /dev/null
+++ b/examples/APG/Svc_Config/Makefile
@@ -0,0 +1,35 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+MAKEFILE=Makefile
+
+MKLIST = Makefile.static \
+ Makefile.dynamic
+
+## Ensure that Makefiles in MKLIST are executed in sequence during a
+## parallel build because we share some files between multiple libraries.
+.NOTPARALLEL:
+
+## Makefile.Reactive_Logging_Server.mkfile is a dummy target which will cause
+## $(MAKE) -f Makefile.Reactive_Logging_Server to be invoked, then it cleans
+## up tempinc when needed for AIX Visual Age C++.
+%.mkfile: %
+ @echo $(MAKE) -f $< $(MKFILE_TARGET)
+ @$(MAKE) -f $< $(MKFILE_TARGET)
+ -@$(RM) -rf tempinc
+
+# This rule invokes make again with the list of .mkfile targets as a
+# parameter. For example, if the all target is being made, make is invoked
+# as follows:
+#
+# make -f Makefile MKFILE_TARGET=all Makefile.static
+
+all clean depend realclean html:
+ifneq ($(MKLIST),)
+ @echo $(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+ @$(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+endif
+
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/examples/APG/Svc_Config/Makefile.dynamic b/examples/APG/Svc_Config/Makefile.dynamic
new file mode 100644
index 00000000000..ccde6b2acef
--- /dev/null
+++ b/examples/APG/Svc_Config/Makefile.dynamic
@@ -0,0 +1,20 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = HA_Configurable_Server_Dynamic
+
+FILES = HA_Status_Dynamic
+SHLIB = libHA_Status.$(SOEXT)
+
+LSRC = $(addsuffix .cpp,$(FILES))
+LOBJ = $(addsuffix .o,$(FILES))
+SHOBJ = $(addsuffix .so,$(FILES))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Svc_Config/Makefile.static b/examples/APG/Svc_Config/Makefile.static
new file mode 100644
index 00000000000..ead34245b11
--- /dev/null
+++ b/examples/APG/Svc_Config/Makefile.static
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = HA_Configurable_Server_Static
+
+SRC = HA_Configurable_Server_Static.cpp HA_Status_Static.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Svc_Config/status.ini b/examples/APG/Svc_Config/status.ini
new file mode 100644
index 00000000000..8a36fb124fa
--- /dev/null
+++ b/examples/APG/Svc_Config/status.ini
@@ -0,0 +1,2 @@
+[HAStatus]
+"ListenPort"=dword:000001ec
diff --git a/examples/APG/Svc_Config/svc.conf.dynamic b/examples/APG/Svc_Config/svc.conf.dynamic
new file mode 100644
index 00000000000..e8ffb12c8ad
--- /dev/null
+++ b/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/examples/APG/Svc_Config/svc.conf.static b/examples/APG/Svc_Config/svc.conf.static
new file mode 100644
index 00000000000..0103380c776
--- /dev/null
+++ b/examples/APG/Svc_Config/svc.conf.static
@@ -0,0 +1 @@
+static HA_Status_Static_Service "-f status.ini"
diff --git a/examples/APG/Svc_Config/svc_config.mpc b/examples/APG/Svc_Config/svc_config.mpc
new file mode 100644
index 00000000000..a877adfb6ae
--- /dev/null
+++ b/examples/APG/Svc_Config/svc_config.mpc
@@ -0,0 +1,22 @@
+project(HA Status) : acelib {
+ sharedname = HA_Status
+ dllflags = HASTATUS_BUILD_DLL
+ Source_Files {
+ HA_Status_Dynamic.cpp
+ }
+}
+
+project(HA Configurable Server Dynamic) : aceexe {
+ exename = HA_Configurable_Server_Dynamic
+ Source_Files {
+ HA_Configurable_Server_Dynamic.cpp
+ }
+}
+
+project(HA Configurable Server Static) : aceexe {
+ exename = HA_Configurable_Server_Static
+ Source_Files {
+ HA_Configurable_Server_Static.cpp
+ HA_Status_Static.cpp
+ }
+}
diff --git a/examples/APG/Svc_Config/svc_config.mwc b/examples/APG/Svc_Config/svc_config.mwc
new file mode 100644
index 00000000000..b048ea34545
--- /dev/null
+++ b/examples/APG/Svc_Config/svc_config.mwc
@@ -0,0 +1,3 @@
+workspace {
+ svc_config.mpc
+}
diff --git a/examples/APG/ThreadManagement/Async_Cancel.cpp b/examples/APG/ThreadManagement/Async_Cancel.cpp
new file mode 100644
index 00000000000..9d07fce2897
--- /dev/null
+++ b/examples/APG/ThreadManagement/Async_Cancel.cpp
@@ -0,0 +1,69 @@
+// $Id$
+
+#include "ace/OS.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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Task<ACE_MT_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate ACE_Task<ACE_MT_SYNCH>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#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/examples/APG/ThreadManagement/Coop_Cancel.cpp b/examples/APG/ThreadManagement/Coop_Cancel.cpp
new file mode 100644
index 00000000000..ab2a940a5da
--- /dev/null
+++ b/examples/APG/ThreadManagement/Coop_Cancel.cpp
@@ -0,0 +1,51 @@
+// $Id$
+
+#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;
+ 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.
+ }
+ }
+
+ 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
diff --git a/examples/APG/ThreadManagement/ExitHandler.cpp b/examples/APG/ThreadManagement/ExitHandler.cpp
new file mode 100644
index 00000000000..85238eac052
--- /dev/null
+++ b/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/examples/APG/ThreadManagement/Makefile b/examples/APG/ThreadManagement/Makefile
new file mode 100644
index 00000000000..359246df7de
--- /dev/null
+++ b/examples/APG/ThreadManagement/Makefile
@@ -0,0 +1,29 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Async_Cancel \
+ Coop_Cancel \
+ ExitHandler \
+ Pool \
+ Priorities \
+ Signals \
+ Signals2 \
+ Start_Hook \
+ State
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/ThreadManagement/Pool.cpp b/examples/APG/ThreadManagement/Pool.cpp
new file mode 100644
index 00000000000..2e843f95f9b
--- /dev/null
+++ b/examples/APG/ThreadManagement/Pool.cpp
@@ -0,0 +1,31 @@
+// $Id$
+
+#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
diff --git a/examples/APG/ThreadManagement/Priorities.cpp b/examples/APG/ThreadManagement/Priorities.cpp
new file mode 100644
index 00000000000..f5fc170a348
--- /dev/null
+++ b/examples/APG/ThreadManagement/Priorities.cpp
@@ -0,0 +1,70 @@
+// $Id$
+
+#include "ace/OS.h"
+#include "ace/Task.h"
+#include "ace/Log_Msg.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;
+ while (this->getq (mb) != -1)
+ process_message (mb);
+ return 0;
+ }
+
+ void process_message (ACE_Message_Block *mb)
+ {
+ 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
+
+// This should be fixed in ACE... There's no _MAX, _MIN values for
+// thread priorities.
+#if defined (ACE_WIN32) && !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX ((ACE_THR_PRI_OTHER_DEF) + 1)
+#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++)
+ {
+ hp_handler.putq (&mb);
+ lp_handler.putq (&mb);
+ }
+
+ hp_handler.wait ();
+ lp_handler.wait ();
+
+ return 0;
+}
+// Listing 1
diff --git a/examples/APG/ThreadManagement/SecurityContext.h b/examples/APG/ThreadManagement/SecurityContext.h
new file mode 100644
index 00000000000..73adbd1a435
--- /dev/null
+++ b/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/examples/APG/ThreadManagement/Signals.cpp b/examples/APG/ThreadManagement/Signals.cpp
new file mode 100644
index 00000000000..08dab1cb0fd
--- /dev/null
+++ b/examples/APG/ThreadManagement/Signals.cpp
@@ -0,0 +1,80 @@
+// $Id$
+
+#include "ace/Task.h"
+#include "ace/Log_Msg.h"
+#include "ace/Signal.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;
+ 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);
+ }
+
+ 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
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Task<ACE_MT_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate ACE_Task<ACE_MT_SYNCH>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/ThreadManagement/Signals2.cpp b/examples/APG/ThreadManagement/Signals2.cpp
new file mode 100644
index 00000000000..2c77f5de606
--- /dev/null
+++ b/examples/APG/ThreadManagement/Signals2.cpp
@@ -0,0 +1,85 @@
+// $Id$
+
+#include "ace/Task.h"
+#include "ace/Log_Msg.h"
+#include "ace/Signal.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;
+ 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);
+ }
+
+ 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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Task<ACE_MT_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate ACE_Task<ACE_MT_SYNCH>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/ThreadManagement/Start_Hook.cpp b/examples/APG/ThreadManagement/Start_Hook.cpp
new file mode 100644
index 00000000000..1fb7cf5f05b
--- /dev/null
+++ b/examples/APG/ThreadManagement/Start_Hook.cpp
@@ -0,0 +1,59 @@
+// $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/examples/APG/ThreadManagement/State.cpp b/examples/APG/ThreadManagement/State.cpp
new file mode 100644
index 00000000000..e5d97c1c22a
--- /dev/null
+++ b/examples/APG/ThreadManagement/State.cpp
@@ -0,0 +1,37 @@
+// $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_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/examples/APG/ThreadManagement/threadmgmt.mpc b/examples/APG/ThreadManagement/threadmgmt.mpc
new file mode 100644
index 00000000000..add73d9fd0d
--- /dev/null
+++ b/examples/APG/ThreadManagement/threadmgmt.mpc
@@ -0,0 +1,62 @@
+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/examples/APG/ThreadManagement/threadmgmt.mwc b/examples/APG/ThreadManagement/threadmgmt.mwc
new file mode 100644
index 00000000000..bba6ac92290
--- /dev/null
+++ b/examples/APG/ThreadManagement/threadmgmt.mwc
@@ -0,0 +1,3 @@
+workspace {
+ threadmgmt.mpc
+}
diff --git a/examples/APG/ThreadPools/Futures.cpp b/examples/APG/ThreadPools/Futures.cpp
new file mode 100644
index 00000000000..181e51f492f
--- /dev/null
+++ b/examples/APG/ThreadPools/Futures.cpp
@@ -0,0 +1,301 @@
+// $Id$
+
+#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"
+
+#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;
+
+ // Block for the result.
+ ((ACE_Future<ACE_CString*>)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, ACE_TEXT ("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 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;
+ 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);
+ }
+
+ int 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 = NULL;
+ 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,
+ "(%t) Worker %d shut down.\n",
+ thread_id(worker)));
+
+ 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
diff --git a/examples/APG/ThreadPools/LF_ThreadPool.cpp b/examples/APG/ThreadPools/LF_ThreadPool.cpp
new file mode 100644
index 00000000000..580f3f038cf
--- /dev/null
+++ b/examples/APG/ThreadPools/LF_ThreadPool.cpp
@@ -0,0 +1,235 @@
+// $Id$
+
+#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 = NULL;
+ 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;
+}
diff --git a/examples/APG/ThreadPools/Makefile b/examples/APG/ThreadPools/Makefile
new file mode 100644
index 00000000000..de54db3218b
--- /dev/null
+++ b/examples/APG/ThreadPools/Makefile
@@ -0,0 +1,25 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Futures \
+ LF_ThreadPool \
+ Task_ThreadPool \
+ ThreadPool \
+ TP_Reactor
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/ThreadPools/Request_Handler.h b/examples/APG/ThreadPools/Request_Handler.h
new file mode 100644
index 00000000000..c534fd57670
--- /dev/null
+++ b/examples/APG/ThreadPools/Request_Handler.h
@@ -0,0 +1,31 @@
+/**
+ * $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"
+class ACE_Thread_Manager;
+
+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/examples/APG/ThreadPools/TP_Reactor.cpp b/examples/APG/ThreadPools/TP_Reactor.cpp
new file mode 100644
index 00000000000..2d67a178d2f
--- /dev/null
+++ b/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/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))
+ == ACE_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::end_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 = * ACE_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
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Accept_Strategy<Request_Handler, ACE_SOCK_ACCEPTOR>;
+template class ACE_Concurrency_Strategy<Request_Handler>;
+template class ACE_Creation_Strategy<Request_Handler>;
+template class ACE_Scheduling_Strategy<Request_Handler>;
+template class ACE_Acceptor<Request_Handler, ACE_SOCK_ACCEPTOR>;
+template class ACE_Strategy_Acceptor<Request_Handler, ACE_SOCK_ACCEPTOR>;
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Accept_Strategy<Request_Handler, ACE_SOCK_ACCEPTOR>
+#pragma instantiate ACE_Concurrency_Strategy<Request_Handler>
+#pragma instantiate ACE_Creation_Strategy<Request_Handler>
+#pragma instantiate ACE_Scheduling_Strategy<Request_Handler>
+#pragma instantiate ACE_Acceptor<Request_Handler, ACE_SOCK_ACCEPTOR>
+#pragma instantiate ACE_Strategy_Acceptor<Request_Handler, ACE_SOCK_ACCEPTOR>
+#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/ThreadPools/Task_ThreadPool.cpp b/examples/APG/ThreadPools/Task_ThreadPool.cpp
new file mode 100644
index 00000000000..0c66f2f3e49
--- /dev/null
+++ b/examples/APG/ThreadPools/Task_ThreadPool.cpp
@@ -0,0 +1,131 @@
+// $Id$
+
+#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 = NULL;
+ 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 = NULL;
+ 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 ();
+ }
+
+ // 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;
+}
diff --git a/examples/APG/ThreadPools/ThreadPool.cpp b/examples/APG/ThreadPools/ThreadPool.cpp
new file mode 100644
index 00000000000..a15be4905a0
--- /dev/null
+++ b/examples/APG/ThreadPools/ThreadPool.cpp
@@ -0,0 +1,252 @@
+// $Id$
+
+#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 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 = NULL;
+ ACE_ASSERT (this->getq (mb) != -1);
+ if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("(%t) Shutting down\n")));
+ 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 = NULL;
+ 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;
+ {
+ 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);
+
+ int 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 = NULL;
+ 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;
+}
+
+int
+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;
+}
diff --git a/examples/APG/ThreadPools/threadpools.mpc b/examples/APG/ThreadPools/threadpools.mpc
new file mode 100644
index 00000000000..17818218490
--- /dev/null
+++ b/examples/APG/ThreadPools/threadpools.mpc
@@ -0,0 +1,34 @@
+project(Futures) : aceexe {
+ 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/examples/APG/ThreadPools/threadpools.mwc b/examples/APG/ThreadPools/threadpools.mwc
new file mode 100644
index 00000000000..efa2761e852
--- /dev/null
+++ b/examples/APG/ThreadPools/threadpools.mwc
@@ -0,0 +1,3 @@
+workspace {
+ threadpools.mpc
+}
diff --git a/examples/APG/ThreadSafety/Atomic_Op.cpp b/examples/APG/ThreadSafety/Atomic_Op.cpp
new file mode 100644
index 00000000000..831c301f652
--- /dev/null
+++ b/examples/APG/ThreadSafety/Atomic_Op.cpp
@@ -0,0 +1,134 @@
+// $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
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+template class ACE_Atomic_Op<ACE_Null_Mutex, int>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+pragma instantiate ACE_Atomic_Op<ACE_Null_Mutex, unsigned int>;
+pragma instantiate ACE_Atomic_Op<ACE_Null_Mutex, int>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/examples/APG/ThreadSafety/Barrier.cpp b/examples/APG/ThreadSafety/Barrier.cpp
new file mode 100644
index 00000000000..880a0bb2095
--- /dev/null
+++ b/examples/APG/ThreadSafety/Barrier.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#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, this->thr_mgr ()->thr_self () * 100);
+ timespec_t t = (timespec_t)tv;
+ ACE_OS::nanosleep (&t);
+}
+
+int
+HA_CommandHandler::handle_command_requests (void)
+{
+ ACE_Time_Value tv (0, this->thr_mgr ()->thr_self () * 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
+
diff --git a/examples/APG/ThreadSafety/ClientContext.h b/examples/APG/ThreadSafety/ClientContext.h
new file mode 100644
index 00000000000..bcd58fc4599
--- /dev/null
+++ b/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/examples/APG/ThreadSafety/Makefile b/examples/APG/ThreadSafety/Makefile
new file mode 100644
index 00000000000..c8cbbd680dc
--- /dev/null
+++ b/examples/APG/ThreadSafety/Makefile
@@ -0,0 +1,28 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Atomic_Op \
+ Barrier \
+ Mutex \
+ RW_Lock \
+ Semaphore \
+ Tokens \
+ Tokens_Deadlock \
+ TSS
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/ThreadSafety/Mutex.cpp b/examples/APG/ThreadSafety/Mutex.cpp
new file mode 100644
index 00000000000..3f8ec3ebb4c
--- /dev/null
+++ b/examples/APG/ThreadSafety/Mutex.cpp
@@ -0,0 +1,54 @@
+// $Id$
+
+#include "ace/Synch.h"
+
+class LogMessage
+{
+public:
+ enum { CRITICAL, NORMAL};
+
+ 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 *msg)
+ {
+ // 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
diff --git a/examples/APG/ThreadSafety/RW_Lock.cpp b/examples/APG/ThreadSafety/RW_Lock.cpp
new file mode 100644
index 00000000000..dafd1f1a61e
--- /dev/null
+++ b/examples/APG/ThreadSafety/RW_Lock.cpp
@@ -0,0 +1,124 @@
+// $Id$
+
+#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;
+}
diff --git a/examples/APG/ThreadSafety/Semaphore.cpp b/examples/APG/ThreadSafety/Semaphore.cpp
new file mode 100644
index 00000000000..dae19b81da2
--- /dev/null
+++ b/examples/APG/ThreadSafety/Semaphore.cpp
@@ -0,0 +1,132 @@
+// $Id$
+
+#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
+
diff --git a/examples/APG/ThreadSafety/TSS.cpp b/examples/APG/ThreadSafety/TSS.cpp
new file mode 100644
index 00000000000..62fea96afb5
--- /dev/null
+++ b/examples/APG/ThreadSafety/TSS.cpp
@@ -0,0 +1,61 @@
+// $Id$
+
+#include "ace/Synch.h"
+#include "ace/Task.h"
+#include "ClientContext.h"
+
+
+void*
+ClientContext::get_attribute (const char *name)
+{
+ void * value;
+ 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;
+}
+
diff --git a/examples/APG/ThreadSafety/Tokens.cpp b/examples/APG/ThreadSafety/Tokens.cpp
new file mode 100644
index 00000000000..3537a5793b5
--- /dev/null
+++ b/examples/APG/ThreadSafety/Tokens.cpp
@@ -0,0 +1,101 @@
+// $Id$
+
+#include "ace/Local_Tokens.h"
+#include "ace/Token_Manager.h"
+#include "ace/Task.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/examples/APG/ThreadSafety/Tokens_Deadlock.cpp b/examples/APG/ThreadSafety/Tokens_Deadlock.cpp
new file mode 100644
index 00000000000..c2d155d5dd6
--- /dev/null
+++ b/examples/APG/ThreadSafety/Tokens_Deadlock.cpp
@@ -0,0 +1,68 @@
+// $Id$
+
+#include "ace/Local_Tokens.h"
+#include "ace/Task.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 ("resource1",
+ 0, // Deadlock detection enabled.
+ 1);// Debugging enabled.
+ mutex1.acquire ();
+ ACE_OS::sleep (2);
+ ACE_Local_Mutex mutex2 ("resource2", 0, 1);
+ mutex2.acquire ();
+ return 0;
+ }
+};
+
+class ThreadTwo : public ACE_Task_Base
+{
+public:
+ virtual int svc (void)
+ {
+ ACE_Local_Mutex mutex2 ("resource2",
+ 0, // Deadlock detection enabled.
+ 1);// Debugging enabled.
+ mutex2.acquire ();
+ ACE_OS::sleep (2);
+ ACE_Local_Mutex mutex1 ("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/examples/APG/ThreadSafety/threadsafety.mpc b/examples/APG/ThreadSafety/threadsafety.mpc
new file mode 100644
index 00000000000..62ed1ddc67a
--- /dev/null
+++ b/examples/APG/ThreadSafety/threadsafety.mpc
@@ -0,0 +1,55 @@
+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 {
+ exename = RW_Lock
+ Source_Files {
+ RW_Lock.cpp
+ }
+}
+
+project(Semaphore) : aceexe {
+ 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/examples/APG/ThreadSafety/threadsafety.mwc b/examples/APG/ThreadSafety/threadsafety.mwc
new file mode 100644
index 00000000000..e6f9f4d2f71
--- /dev/null
+++ b/examples/APG/ThreadSafety/threadsafety.mwc
@@ -0,0 +1,3 @@
+workspace {
+ threadsafety.mpc
+}
diff --git a/examples/APG/Threads/Activate.cpp b/examples/APG/Threads/Activate.cpp
new file mode 100644
index 00000000000..49ca90327a4
--- /dev/null
+++ b/examples/APG/Threads/Activate.cpp
@@ -0,0 +1,30 @@
+// $Id$
+
+// Listing 1 code/ch12
+#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")));
+ 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);
+
+ handler.wait ();
+ return 0;
+}
+// Listing 1
diff --git a/examples/APG/Threads/Condition_Variables.cpp b/examples/APG/Threads/Condition_Variables.cpp
new file mode 100644
index 00000000000..c8cd03c9776
--- /dev/null
+++ b/examples/APG/Threads/Condition_Variables.cpp
@@ -0,0 +1,105 @@
+// $Id$
+
+#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
+
+
diff --git a/examples/APG/Threads/Guards.cpp b/examples/APG/Threads/Guards.cpp
new file mode 100644
index 00000000000..75c40c98594
--- /dev/null
+++ b/examples/APG/Threads/Guards.cpp
@@ -0,0 +1,52 @@
+// $Id$
+
+#if 0
+
+// 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
+// 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.
+ // ...
+}
+// Listing 3
+
+#endif /* 0 */
+int main (int, char *[])
+{ return 0; }
diff --git a/examples/APG/Threads/Makefile b/examples/APG/Threads/Makefile
new file mode 100644
index 00000000000..b1331914740
--- /dev/null
+++ b/examples/APG/Threads/Makefile
@@ -0,0 +1,26 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Activate \
+ Condition_Variables \
+ Guards \
+ Message_Blocks \
+ Message_Queue \
+ Mutexes
+
+SOURCES = $(addsuffix .cpp,$(BIN))
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
diff --git a/examples/APG/Threads/Message_Blocks.cpp b/examples/APG/Threads/Message_Blocks.cpp
new file mode 100644
index 00000000000..3ddf3ba8a5b
--- /dev/null
+++ b/examples/APG/Threads/Message_Blocks.cpp
@@ -0,0 +1,40 @@
+// $Id$
+
+int main (int, char **)
+{
+#if 0
+
+// 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
+// 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 --> %s\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
+#endif
+ return 0;
+}
diff --git a/examples/APG/Threads/Message_Queue.cpp b/examples/APG/Threads/Message_Queue.cpp
new file mode 100644
index 00000000000..72eff4aa1ac
--- /dev/null
+++ b/examples/APG/Threads/Message_Queue.cpp
@@ -0,0 +1,164 @@
+// $Id$
+
+#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)
+{
+ int result =
+ this->peer ().recv_n (mb->wr_ptr (), payload_length);
+
+ if (result <= 0)
+ {
+ mb->release ();
+ return result;
+ }
+
+ 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::run_event_loop ();
+ //run the reactive event loop
+
+ handler.wait ();
+ //reap the handler before exiting.
+
+ return 0;
+}
diff --git a/examples/APG/Threads/Message_Receiver.h b/examples/APG/Threads/Message_Receiver.h
new file mode 100644
index 00000000000..dee0731f007
--- /dev/null
+++ b/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/examples/APG/Threads/Mutexes.cpp b/examples/APG/Threads/Mutexes.cpp
new file mode 100644
index 00000000000..2b8903bf05f
--- /dev/null
+++ b/examples/APG/Threads/Mutexes.cpp
@@ -0,0 +1,61 @@
+// $Id$
+
+#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
+
diff --git a/examples/APG/Threads/threads.mpc b/examples/APG/Threads/threads.mpc
new file mode 100644
index 00000000000..ff7c8e5063d
--- /dev/null
+++ b/examples/APG/Threads/threads.mpc
@@ -0,0 +1,41 @@
+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/examples/APG/Threads/threads.mwc b/examples/APG/Threads/threads.mwc
new file mode 100644
index 00000000000..ddbb9c065b9
--- /dev/null
+++ b/examples/APG/Threads/threads.mwc
@@ -0,0 +1,3 @@
+workspace {
+ threads.mpc
+}
diff --git a/examples/APG/Timers/Alarm.cpp b/examples/APG/Timers/Alarm.cpp
new file mode 100644
index 00000000000..ae79b5feefd
--- /dev/null
+++ b/examples/APG/Timers/Alarm.cpp
@@ -0,0 +1,51 @@
+// $Id$
+
+// 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 = ACE_static_cast (const int*, arg);
+ ACE_ASSERT ((*val) == id_);
+
+ 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);
+ return 0; // Not reached.
+}
+// Listing 2
diff --git a/examples/APG/Timers/CB.cpp b/examples/APG/Timers/CB.cpp
new file mode 100644
index 00000000000..329fed58a4b
--- /dev/null
+++ b/examples/APG/Timers/CB.cpp
@@ -0,0 +1,62 @@
+// $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 = ACE_static_cast (const int*, arg);
+ ACE_ASSERT ((*val) == 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);
+ ACE_ASSERT (Timer::instance ()->reset_interval
+ (timerID_, interval) != -1);
+ }
+
+ 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/examples/APG/Timers/CB.h b/examples/APG/Timers/CB.h
new file mode 100644
index 00000000000..716ad4e4f50
--- /dev/null
+++ b/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/examples/APG/Timers/Makefile b/examples/APG/Timers/Makefile
new file mode 100644
index 00000000000..37590afa196
--- /dev/null
+++ b/examples/APG/Timers/Makefile
@@ -0,0 +1,36 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+MAKEFILE=Makefile
+
+MKLIST = Makefile.singles \
+ Makefile.timers \
+ Makefile.upcall
+
+## Ensure that Makefiles in MKLIST are executed in sequence during a
+## parallel build because we share some files between multiple libraries.
+.NOTPARALLEL:
+
+## Makefile.Reactive_Logging_Server.mkfile is a dummy target which will cause
+## $(MAKE) -f Makefile.Reactive_Logging_Server to be invoked, then it cleans
+## up tempinc when needed for AIX Visual Age C++.
+%.mkfile: %
+ @echo $(MAKE) -f $< $(MKFILE_TARGET)
+ @$(MAKE) -f $< $(MKFILE_TARGET)
+ -@$(RM) -rf tempinc
+
+# This rule invokes make again with the list of .mkfile targets as a
+# parameter. For example, if the all target is being made, make is invoked
+# as follows:
+#
+# make -f Makefile MKFILE_TARGET=all Makefile.singles
+
+all clean depend realclean html:
+ifneq ($(MKLIST),)
+ @echo $(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+ @$(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+endif
+
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/examples/APG/Timers/Makefile.singles b/examples/APG/Timers/Makefile.singles
new file mode 100644
index 00000000000..cc857d6c4ba
--- /dev/null
+++ b/examples/APG/Timers/Makefile.singles
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Alarm Task
+
+BUILD = $(VBIN)
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/Makefile.timers b/examples/APG/Timers/Makefile.timers
new file mode 100644
index 00000000000..4d63a0c56cb
--- /dev/null
+++ b/examples/APG/Timers/Makefile.timers
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Timers
+
+SRC = Timers.cpp CB.cpp TimerDispatcher.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/Makefile.upcall b/examples/APG/Timers/Makefile.upcall
new file mode 100644
index 00000000000..859a20278c7
--- /dev/null
+++ b/examples/APG/Timers/Makefile.upcall
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Upcall
+
+SRC = Upcall.cpp PCB.cpp PTimerDispatcher.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/PCB.cpp b/examples/APG/Timers/PCB.cpp
new file mode 100644
index 00000000000..ce5c8d556f3
--- /dev/null
+++ b/examples/APG/Timers/PCB.cpp
@@ -0,0 +1,70 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "PCB.h"
+#include "PTimerDispatcher.h"
+
+PCB::PCB() : count_(0)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::PCB"));
+}
+
+int PCB::handleEvent (const void *arg)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::handle_timeout"));
+
+ const int *val = ACE_static_cast(const int*, arg);
+ ACE_ASSERT ((*val) == timerID_);
+
+ 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);
+ ACE_ASSERT (PTimer::instance ()->reset_interval
+ (timerID_, interval) != -1);
+ }
+
+ if (count_++ == 10)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Canceling %d\n"),
+ timerID_));
+ ACE_ASSERT ((PTimer::instance ()->cancel (this)) != 0);
+ }
+
+ return 0;
+}
+
+void
+PCB::setID (long timerID)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::setID"));
+ timerID_ = timerID;
+}
+
+long
+PCB::getID (void)
+{
+ 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/examples/APG/Timers/PCB.h b/examples/APG/Timers/PCB.h
new file mode 100644
index 00000000000..9f82e4652cd
--- /dev/null
+++ b/examples/APG/Timers/PCB.h
@@ -0,0 +1,28 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(PCB_H)
+#define PCB_H
+
+// Listing 1 code/ch20
+class PCB
+{
+public:
+ PCB ();
+
+ // Set/get the timer id that is being handled by this instance.
+ void setID (long timerID);
+ long getID (void);
+
+ // 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/examples/APG/Timers/PTimerDispatcher.cpp b/examples/APG/Timers/PTimerDispatcher.cpp
new file mode 100644
index 00000000000..50a51b99115
--- /dev/null
+++ b/examples/APG/Timers/PTimerDispatcher.cpp
@@ -0,0 +1,64 @@
+// $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);
+}
diff --git a/examples/APG/Timers/PTimerDispatcher.h b/examples/APG/Timers/PTimerDispatcher.h
new file mode 100644
index 00000000000..8a530f41709
--- /dev/null
+++ b/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/examples/APG/Timers/Task.cpp b/examples/APG/Timers/Task.cpp
new file mode 100644
index 00000000000..8b338df69c4
--- /dev/null
+++ b/examples/APG/Timers/Task.cpp
@@ -0,0 +1,69 @@
+// $Id$
+
+// 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 &tv,
+ const void *arg)
+ {
+ ACE_TRACE (ACE_TEXT ("CB::handle_timeout"));
+
+ const int *val = ACE_static_cast (const int*, arg);
+ ACE_ASSERT((*val) == id_);
+ 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 argc, ACE_TCHAR *argv[])
+{
+ 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, 1000);
+
+ long tid1 = atimer.schedule (&cb1,
+ &arg1,
+ curr_tv + ACE_Time_Value (3L),
+ interval);
+ long tid2 = 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/examples/APG/Timers/TimerDispatcher.cpp b/examples/APG/Timers/TimerDispatcher.cpp
new file mode 100644
index 00000000000..1d5bf5a77ba
--- /dev/null
+++ b/examples/APG/Timers/TimerDispatcher.cpp
@@ -0,0 +1,68 @@
+// $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);
+}
diff --git a/examples/APG/Timers/TimerDispatcher.h b/examples/APG/Timers/TimerDispatcher.h
new file mode 100644
index 00000000000..fc519b77615
--- /dev/null
+++ b/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/examples/APG/Timers/Timers.cpp b/examples/APG/Timers/Timers.cpp
new file mode 100644
index 00000000000..fc5a21e596e
--- /dev/null
+++ b/examples/APG/Timers/Timers.cpp
@@ -0,0 +1,57 @@
+// $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 argc, ACE_TCHAR *argv[])
+{
+ 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 (int i = 0; i < 10 ; i++)
+ {
+ long timerID =
+ Timer::instance ()->schedule
+ (&cb[i],
+ &args[i],
+ timer_queue->gettimeofday () + (ACE_Time_Value)5,
+ i);
+
+ // 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/examples/APG/Timers/Upcall.cpp b/examples/APG/Timers/Upcall.cpp
new file mode 100644
index 00000000000..1a3294cf5a9
--- /dev/null
+++ b/examples/APG/Timers/Upcall.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "Upcall.h"
+#include "PTimerDispatcher.h"
+
+// Listing 2 code/ch20
+int
+UpcallHandler::timeout (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg,
+ const ACE_Time_Value &cur_time)
+{
+ ACE_TRACE (ACE_TEXT ("UpcallHandler::timeout"));
+
+ return (*handler).handleEvent (arg);
+}
+
+int
+UpcallHandler::cancellation (PTimerQueue &timer_queue,
+ 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 ();
+}
+
+// This method is called when the timer is canceled
+int
+UpcallHandler::deletion (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg)
+{
+ 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
+
+
+// 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, 1);
+ PTimer::instance ()->schedule (&cb2, &arg2, tv, 2);
+
+ // Run the timer event loop forever.
+ PTimer::instance ()->wait_for_event ();
+
+ return 0;
+}
+// Listing 3
diff --git a/examples/APG/Timers/Upcall.h b/examples/APG/Timers/Upcall.h
new file mode 100644
index 00000000000..e14532afb3b
--- /dev/null
+++ b/examples/APG/Timers/Upcall.h
@@ -0,0 +1,44 @@
+/* -*- 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:
+ int timeout (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg,
+ const ACE_Time_Value &cur_time);
+
+ // This method is called when the timer is canceled.
+ int cancellation (PTimerQueue &timer_queue,
+ PCB *handler);
+
+ // 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);
+};
+
+#endif /*UPCALL_H*/
diff --git a/examples/APG/Timers/timers.mpc b/examples/APG/Timers/timers.mpc
new file mode 100644
index 00000000000..3dc5724b752
--- /dev/null
+++ b/examples/APG/Timers/timers.mpc
@@ -0,0 +1,31 @@
+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
+ }
+}
diff --git a/examples/APG/Timers/timers.mwc b/examples/APG/Timers/timers.mwc
new file mode 100644
index 00000000000..b3032dea82d
--- /dev/null
+++ b/examples/APG/Timers/timers.mwc
@@ -0,0 +1,3 @@
+workspace {
+ timers.mpc
+}